Cod sursa(job #1780507)

Utilizator TibiraducanuTiberiu Raducanu Tibiraducanu Data 16 octombrie 2016 12:22:14
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

const int N=2005,K=20;
const long long Inf=(1ll<<60)-1;
int n,m,k,a,b,c,v[K],mat[K][N],pos[N];
bool check[N],sem;
long long dist[N],d[(1<<K)][K];

struct ii{
    long long dist;
    int nod;
};
struct ij{
    int dist,nod;
};
struct cmp{
    bool operator() (ii &a,ii &b){
        return a.dist>b.dist;
    }
};
vector <ij> G[N];
priority_queue< ii, vector<ii>, cmp > pq;

void Dijkstra(int t){
    int i,x,y;
    long long d;
    for(i=1;i<=n;i++) dist[i]=Inf;
    dist[t]=0;
    pq.push({0ll,t});

    while(!pq.empty()){
        d=pq.top().dist;
        x=pq.top().nod;
        pq.pop();
        if(d>dist[x]) continue;

        for(i=0;i<(int)G[x].size();i++){
            y=G[x][i].nod;
            d=G[x][i].dist;

            if(dist[x]+d<dist[y]){
                dist[y]=dist[x]+d;
                pq.push({dist[y],y});
            }
        }
    }
}



int main(){
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);

    int i,j;
    scanf("%d%d",&n,&m);
    scanf("%d",&k);
    for(i=0;i<k;i++){
        scanf("%d",&v[i]);
        check[v[i]]=1;
        pos[v[i]]=i;
    }
    check[1]=1, check[n]=1;
    pos[1]=k, pos[n]=k+1;
    v[k]=1, v[k+1]=n, k+=2;
    for(i=1;i<=m;i++){
        scanf("%d%d%d",&a,&b,&c);
        G[a].push_back({c,b});
        G[b].push_back({c,a});
    }

    for(i=0;i<k;i++){
        Dijkstra(v[i]);
        for(j=1;j<=n;j++)
            mat[i][j]=dist[j];
    }

    /// mat[i][j]= drumul minim de la nodul v[i] la nodul j;

    int x,y;
    for(i=0;i<k;i++)
        d[(1<<i)][i]=1ll*mat[i][1];

    for(i=1;i<(1<<k);i++)
        for(j=0;j<k;j++)
            if(i&(1<<j)){
                //if(d[i][j]==0ll) d[i][j]=Inf;
                //printf("|%d %d|\n",i,j);
                sem=0;

                for(int t=0;t<(int)G[v[j]].size();t++){
                    y=G[v[j]][t].nod;
                    //printf("%d ",y);
                    x=pos[y];
                    if(check[y]){
                        //printf("<3 ");
                        if(i&(1<<x)){
                            //printf("{%d %d}",x,v[j]);
                            if(sem==0){
                                d[i][j]=d[i^(1<<j)][x]+mat[x][v[j]];
                                sem=1;
                            }
                            else
                                d[i][j]=min(d[i][j], d[i^(1<<j)][x]+mat[x][j]);
                        }
                    }
                    //printf("  ");
                }
                //printf("\n");
            }

    /*printf("\n");
    for(i=1;i<(1<<k);i++)
    {
        for(j=0;j<k;j++) printf("%d ",d[i][j]);
        printf("\n");
    }*/

    printf("%d\n",d[(1<<k)-1][k-1]);



    return 0;
}