Cod sursa(job #1896720)

Utilizator ionut98Bejenariu Ionut Daniel ionut98 Data 28 februarie 2017 20:56:57
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.1 kb
#include<fstream>
#include<queue>
#include<vector>
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
const int inf=1000000005;
vector<int>ls[2005],lc[2005];
int dist[20][2005],n,m,x,y,c,i,j,w,k,cb[20];
int sol[33000][15];
void bf(int k)
{
    int i,l,y;
    x=cb[k];
    queue<int>q;
    q.push(x);
    for(i=1;i<=n;i++)//initializez matricea de adiacenta cu costuri
      dist[k][i]=inf;
    dist[k][x]=0;
    while(q.empty()==0) //actualizez costurile de la nodul k la fiecare nod
    {
        x=q.front();
        l=ls[x].size();
        q.pop();
        for(i=0;i<l;i++)
        {
            y=ls[x][i];
            if(dist[k][x]+lc[x][i]<dist[k][y])
            {
                dist[k][y]=dist[k][x]+lc[x][i];
                q.push(y);
            }
        }
    }
}
int main()
{
    f>>n>>m>>k;
    for(i=0;i<k;i++)//nodurile obligatorii
      f>>cb[i];
    for(i=1;i<=m;i++) //vector de adiacenta si vector de costuri
    {
        f>>x>>y>>c;
        ls[x].push_back(y);
        lc[x].push_back(c);
        ls[y].push_back(x);
        lc[y].push_back(c);
    }
    if(k==0)//nu am noduri obligatorii
    {
        cb[1]=1;
        bf(1);
        g<<dist[1][n];
    }
    else
    {
        for(i=0;i<k;i++)//construiesc matricea de costuril pentru fiecare nod obligatoriu
          bf(i);
        for(i=0;i<=(1<<k);i++)//initializez matricea pentru solutii
          for(j=0;j<=n;j++)
            sol[i][j]=inf;
        for(i=0;i<k;i++)//iau fiecare nod obligaroriu pe rand
          sol[(1<<i)][i]=dist[i][1];//retin distanta de la fiecare la nodul de plecare 1
        for(i=1;i<(1<<k);i++)
          for(j=0;j<k;j++)
            if((i&(1<<j)))
              for(w=0;w<k;w++)
                if(w!=j&&(i&(1<<w)))
                  sol[i][j]=min(sol[i][j],sol[i^(1<<j)][w]+dist[w][cb[j]]);//construiesc solutia minima in functie de distanta spre nodurile obligatorii
        int min1=inf;
        for(i=0;i<k;i++)
          min1=min(min1,sol[(1<<k)-1][i]+dist[i][n]);//caut distanta minima
        g<<min1;
    }
    return 0;
}