Cod sursa(job #1295710)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 20 decembrie 2014 00:58:20
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int N=2000,K=17,INF=2000000000;
class To{
    public:
        int v,c;
        To(){
        }
        To(int vv,int cc){
            v=vv;
            c=cc;
        }
        bool operator<(const To&to)const{
            if(to.c==c)
                return to.v<v;
            return to.c<c;
        }
};
priority_queue<To>h;
vector<To>g1[N+1];
vector<To>g2[K+1];
int n,m,k;
int c[K+1];
int pos[N+1];
int dist[N+1];
int d[(1<<K)+1][K+1];
void dijkstra(int node){
    int cnode=node;
    node=c[node];
    memset(dist,0,sizeof(dist));
    h.push(To(node,0));
    while(!h.empty()){
        To dad=h.top();
        h.pop();
        for(unsigned i=0;i<g1[dad.v].size();i++){
            To son=g1[dad.v][i];
            if(son.v!=node&&(dist[son.v]==0||dist[dad.v]+son.c<dist[son.v])){
                dist[son.v]=dist[dad.v]+son.c;
                h.push(To(son.v,dist[son.v]));
            }
        }
    }
    for(int i=0;i<k;i++)
        if(c[i]!=node)
            if(dist[c[i]]>0)
                g2[cnode].push_back(To(pos[c[i]],dist[c[i]]));
}
int DP(int p,int node){
    if(d[p][node]>0)
        return d[p][node];
    if(node==0)
        return 0;
    int minD=INF+1;
    for(unsigned int i=0;i<g2[node].size();i++){
        To son=g2[node][i];
        if(son.v==0&&p!=(1<<node)+1)
            continue;
        int pp=1<<son.v;
        if((p/pp)%2==1)
            minD=min(minD,DP(p-(1<<node),son.v)+son.c);
    }
    d[p][node]=minD;
    return minD;
}
int main(){
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=k;i++){
        scanf("%d",&c[i]);
        pos[c[i]]=i;
    }
    pos[n]=++k;
    c[0]=1;
    c[k++]=n;
    for(int i=1;i<=m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        g1[x].push_back(To(y,z));
        g1[y].push_back(To(x,z));
    }
    for(int i=0;i<k;i++)
        dijkstra(i);
    printf("%d",DP((1<<k)-1,k-1));
    return 0;
}