Cod sursa(job #1857127)

Utilizator dragos_vecerdeaVecerdea Dragos dragos_vecerdea Data 25 ianuarie 2017 20:39:56
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.26 kb
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
#define INF 2000000
#define MAXN 2011

FILE *fin=fopen("ubuntzei.in","r");
FILE *fout = fopen("ubuntzei.out","w");
int best[MAXN][MAXN];
int vizitat[MAXN];
int cnt[MAXN];
int bit(int i,int j)
{
    return i&(1<<j);
}

int trebuie[MAXN];
int drum[MAXN][34000];
struct pereche
{
    int muc;
    int cost;
};
vector <pereche> muchie[MAXN];
int main()
{
    int n,m,k;
    fscanf(fin,"%d%d%d",&n,&m,&k);
    for(int j=0;j<k;j++)
    {
        fscanf(fin,"%d",&trebuie[j]);
    }
    for(int j=0;j<m;j++)
    {
        int x,y,z;
        fscanf(fin,"%d%d%d",&x,&y,&z);
        muchie[y].push_back(pereche{x,z});
        muchie[x].push_back(pereche{y,z});

    }
    trebuie[k]=1;
    for(int i=0;i<=k;i++)
        for(int j=1;j<=n;j++)
    {
        if(j!=trebuie[i])
        {
            best[trebuie[i]][j]=INF;
        }
    }
    for(int i=0;i<=k;i++)
    {
        for(int j=1;j<=n;j++)
        {
            vizitat[j]=0;
            cnt[j]=0;
        }
        queue <int> frontiera;
        cnt[trebuie[i]]=1;
        int ok=1;
        vizitat[trebuie[i]]=1;
        frontiera.push(trebuie[i]);
        while(!frontiera.empty() && ok==1)
        {
            int nod=frontiera.front();
            //fprintf(stderr, "%d: ", nod);
            vizitat[nod]=0;
            frontiera.pop();
            for(pereche 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)
                    {
                        cnt[node.muc]++;
                        vizitat[node.muc]=1;
                        if(cnt[node.muc]>n)ok=0;
                        frontiera.push(node.muc);
                        //fprintf(stderr, "%d ", node.muc);
                    }
                }
            }
            //fprintf(stderr, "\n");
        }
        //fprintf(stderr, "\n");
    }
    /*
    for(int i = 1; i <= n; i++) {
      fprintf(stderr, "%d ", best[1][i]);
    }
    fprintf(stderr, "\n");
    for(int i = 1; i <= n; i++) {
      fprintf(stderr, "%d ", best[2][i]);
    }
    fprintf(stderr, "\n");//*/
    for(int i=0;i<k;i++)
    {
        for(int j=0;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))
            {
                for(int q=0;q<k;q++)
                {
                    if(q!=j && bit(i,q))
                    {
                        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;
    minim=drum[trebuie[0]][(1<<k)-1]+best[trebuie[0]][n];
    for(int i=0;i<k;i++)
    {
        if(minim>best[trebuie[i]][n]+drum[trebuie[i]][(1<<k)-1])
           minim=best[trebuie[i]][n]+drum[trebuie[i]][(1<<k)-1];
    }
    if(k!=0)fprintf(fout,"%d",minim);
    else fprintf(fout,"%d",best[1][n]);
    return 0;
}