Cod sursa(job #1383712)

Utilizator alecsandrualex cuturela alecsandru Data 10 martie 2015 16:10:34
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.48 kb
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int INF=0x3fffffff;
const int MAXN=2050;
const int MAXM=10050;
const int MAXK=(1<<17)+5;

struct DRUM
{
    int cost,fiu;
};

struct NOD
{
    int nod,goal;
};

int important[MAXN],cost[25][MAXK],tcost[20][MAXN];
int best[20][20];
bool inqueue[20][MAXK];
vector <DRUM> drum[MAXN];
vector <int> vip;
NOD tata,fiu;
queue <NOD> q;
bool iq[MAXK + 1],viz[MAXK + 1];
int main()
{
    int n,m,k,i,j;
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    scanf("%d%d",&n,&m);
    scanf("%d",&k);
    int cnt=0;
    vip.push_back(0);
    for(i=1;i<=k;i++)
    {
        scanf("%d",&j);
        important[j]=i;
        vip.push_back(j);
    }
    if(important[1]==0)
    {
        important[1]=k+1;
        k++;
        vip.push_back(1);
    }
    if(important[n]==0)
    {
        important[n]=k+1;
        k++;
        vip.push_back(n);
    }
    int x,y,c;
    DRUM temp;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&c);
        temp.fiu=x;
        temp.cost=c;
        drum[y].push_back(temp);
        temp.fiu=y;
        drum[x].push_back(temp);
    }

    for(i=1;i<=k;i++)
        for(j=1;j<=n;j++)
            tcost[i][j]=INF;

    for(cnt=1;cnt<=k;cnt++)
    {
        tata.nod=vip[cnt];
        q.push(tata);
        tcost[cnt][tata.nod]=0;
        iq[tata.nod]=1;
        while(!q.empty())
        {
            tata=q.front();
            //printf("%d\n",tata.nod);
            q.pop();
            iq[tata.nod]=0;
            if(important[tata.nod])
            {
                best[cnt][important[tata.nod]]=tcost[cnt][tata.nod];
                best[important[tata.nod]][cnt]=best[cnt][important[tata.nod]];
            }
            for(j=0;j<drum[tata.nod].size();j++)
            {
                fiu.nod=drum[tata.nod][j].fiu;
                if(tcost[cnt][tata.nod]+drum[tata.nod][j].cost<tcost[cnt][fiu.nod])
                {
                    tcost[cnt][fiu.nod]=tcost[cnt][tata.nod]+drum[tata.nod][j].cost;
                    if(iq[fiu.nod]==0)
                    {
                        iq[fiu.nod]=1;
                        q.push(fiu);
                    }
                }
            }
        }
    }
    /*
    for(i=1;i<=k;i++)
    {
        for(j=1;j<=k;j++)
            printf("%d ",best[i][j]);
        printf("\n");
    }//*/
    int lim=(1<<k)-1;
    for(i=1;i<=k;i++)
        for(j=0;j<=lim;j++)
            cost[i][j]=INF;
    tata.nod=1;
    tata.goal=1<<(tata.nod-1);
    q.push(tata);
    inqueue[tata.nod][tata.goal]=true;
    cost[tata.nod][tata.goal]=0;
    while(!q.empty())
    {
        //printf("%d %d\n",tata.nod,tata.goal);
        tata=q.front();
        q.pop();
        inqueue[tata.nod][tata.goal]=false;
        for(i=1;i<=k;i++)
        {
            fiu.nod=i;
            if(((1<<(fiu.nod-1))&tata.goal)>0)
                continue;
            fiu.goal=tata.goal | (1<<(fiu.nod-1));
            if(cost[tata.nod][tata.goal]+best[tata.nod][fiu.nod]<cost[fiu.nod][fiu.goal])
            {
                cost[fiu.nod][fiu.goal]=cost[tata.nod][tata.goal]+best[tata.nod][fiu.nod];
                if(inqueue[fiu.nod][fiu.goal]==false)
                {
                    inqueue[fiu.nod][fiu.goal]=true;
                    q.push(fiu);
                }
            }
        }
    }
    printf("%d",cost[important[n]][lim]);
    return 0;
}