Cod sursa(job #982860)

Utilizator stefanzzzStefan Popa stefanzzz Data 10 august 2013 13:18:56
Problema Gather Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <fstream>
#include <vector>
#include <queue>
#include <set>
#define MAXK 20
#define MAXN 755
using namespace std;
ifstream f("gather.in");
ofstream g("gather.out");

struct muchie{
    int nod,lg,dmax;};
struct el_pq{
    int nod,dst,cod;};

struct Comp{
    bool operator()(el_pq a,el_pq b){
        return a.dst>b.dst;}};

struct Comp2{
    bool operator()(el_pq a,el_pq b){
        if(a.nod==b.nod)
            return a.cod<b.cod;
        return a.nod<b.nod;}};

int n,m,k,a,b,celula[MAXK],detinut[MAXN],nrd;
vector<muchie> G[MAXN];
muchie aux;
el_pq x;
set < el_pq,Comp2> uz;
set < el_pq,Comp2>::iterator it;
priority_queue<el_pq,vector<el_pq>,Comp> pq;
bool luat[MAXK];

int main()
{
    int i;
    f>>k>>n>>m;
    for(i=1;i<=n;i++)
        detinut[i]=celula[i]=-1;
    for(i=0;i<k;i++){
        f>>celula[i];
        detinut[celula[i]]=i;}
    for(i=1;i<=m;i++){
        f>>a>>b>>aux.lg>>aux.dmax;
        aux.nod=b;
        G[a].push_back(aux);
        aux.nod=a;
        G[b].push_back(aux);}
    x.nod=1;
    x.dst=x.cod=0;
    pq.push(x);
    uz.insert(x);
    if(detinut[1]!=-1){
        x.cod=(1<<detinut[i]);
        pq.push(x);
        uz.insert(x);}
    while(1){
        x=pq.top();
        pq.pop();
        while(x.dst>(*uz.find(x)).dst){
            x=pq.top();
            pq.pop();}
        if(x.cod==(1<<k)-1)
            break;
        a=x.nod;
        nrd=0;
        for(i=0;i<k;i++){
            if((1<<i)&x.cod){
                luat[i]=1;
                nrd++;}
            else
                luat[i]=0;}
        for(i=0;i<G[a].size();i++){
            aux=G[a][i];
            if(aux.dmax>=nrd){
                x.nod=aux.nod;
                x.dst+=aux.lg*(nrd+1);
                it=uz.find(x);
                if(it==uz.end()||(*it).dst>x.dst){
                    pq.push(x);
                    if(it!=uz.end())
                        uz.erase(it);
                    uz.insert(x);}
                if(detinut[aux.nod]==-1||luat[detinut[aux.nod]]){
                    x.dst-=aux.lg*(nrd+1);
                    continue;}
                x.cod+=(1<<detinut[aux.nod]);
                it=uz.find(x);
                if(it==uz.end()||(*it).dst>x.dst){
                    pq.push(x);
                    if(it!=uz.end())
                        uz.erase(it);
                    uz.insert(x);}
                x.cod-=(1<<detinut[aux.nod]);
                x.dst-=aux.lg*(nrd+1);}}}
    g<<x.dst<<'\n';
    f.close();
    g.close();
    return 0;
}