Cod sursa(job #1855977)

Utilizator dragos_vecerdeaVecerdea Dragos dragos_vecerdea Data 24 ianuarie 2017 13:48:02
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
FILE *fin=fopen("ubuntzei.in","r");
FILE *fout = fopen("ubuntzei.out","w");
int best[20][20];
char vizitat[20];
int bit(int i,int j)
{
    return i&(1<<j);
}
#define INF 2000000
#define MAXN 2011
int trebuie[MAXN];
int drum[MAXN][34000];
struct pereche
{
    int muc,cost;
};
vector <pereche> muchie[MAXN];
int main()
{
    int n,m,k;
    fscanf(fin,"%d%d",&n,&m);
    fscanf(fin,"%d",&k);
    for(int i=0;i<k;i++)
    {
        fscanf(fin,"%d",&trebuie[i]);
    }
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        fscanf(fin,"%d%d%d",&x,&y,&z);
        muchie[x].push_back({y,z});
        muchie[y].push_back({x,z});
    }
    for(int i=0;i<k;i++)
    {
        for(int j=1;j<=n;j++)
        {
            best[trebuie[i]][j]=INF;
        }
        queue <int> frontiera;
        best[trebuie[i]][trebuie[i]]=0;
        frontiera.push(trebuie[i]);
        while(!frontiera.empty())
        {
            int nod=frontiera.back();
            vizitat[nod]=0;
            frontiera.pop();
            for(auto node:muchie[nod])
            {
                if(best[trebuie[i]][nod]+node.cost<best[trebuie[i]][node.muc])
                {
                    best[trebuie[i]][node.muc]=best[trebuie[i]][nod]+node.cost;
                    if(vizitat[node.muc]==0)
                    {
                        vizitat[node.muc]=1;
                        frontiera.push(node.muc);
                    }
                }
            }
        }
    }
    for(int i=0;i<k;i++)
        for(int j=1;j< 1<<k ;j++)
    {
        drum[trebuie[i]][j]=INF;
    }
    for(int i=0;i<k;i++)
    {
        drum[trebuie[i]][1<<i]=best[trebuie[i]][1];
    }
    for(int i=1;i<(1<<k);i++)
    {
        for(int j=0;j<k;j++)
        {
            if(bit(i,j)!=0)
            {
                for(int q=0;q<k;q++)
                {
                    if(q!=j && bit(i,q)!=0)
                    {
                        if(drum[trebuie[j]][i]>drum[trebuie[q]][i-(1<<j)]+best[trebuie[q]][trebuie[j]])drum[trebuie[j]][i]=drum[trebuie[q]][i-(1<<j)]+best[trebuie[q]][trebuie[j]];
                    }

                }
            }
        }
    }
    int minim=INF;
    for(int i=0;i<k;i++)
    {
        if(best[trebuie[i]][n]+drum[trebuie[i]][(1<<k)-1]<minim)minim=best[trebuie[i]][n]+drum[trebuie[i]][(1<<k)-1];
    }
    fprintf(fout,"%d",minim);
    return 0;
}