Cod sursa(job #1892851)

Utilizator hasmasandragosHasmasan Dragos hasmasandragos Data 25 februarie 2017 12:26:53
Problema Ubuntzei Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.62 kb
#include <bits/stdc++.h>
using namespace std;

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

const int nmax=375;
const int logmax=((1<<17)-1)+5;

int n,m,k;
int stops[nmax]; /// orasele marcate
int cost[nmax][nmax]; /// dist min de la i la j
int prieteni[20]; /// vectorul de prieteni
int dp[20][logmax]; /// dp[i][j] = costul minim pana in nodul i cu configuratia j
int ini[20]; /// just a little something
vector <pair <int,int> > graf_ini[nmax]; /// nod , cost
vector <pair <int,int> > graf_min[20]; /// nod , cost
priority_queue <pair <int, pair<int,int> > , vector < pair <int, pair<int,int> > > , greater < pair <int, pair <int,int> > > > cod_minim; /// cost , nod , stare
priority_queue <pair <int,int> , vector <pair <int,int> > , greater <pair <int,int> > > cod_normal; /// cost , nod

void dijkstra_normal (int nod_ini) /// pt graful normal
{
    int i,nodac,costac,vecini,nodnou,costnou;
    cost[nod_ini][nod_ini]=0;
    cod_normal.push(make_pair(0,nod_ini));

    while (!cod_normal.empty())
    {
        costac=cod_normal.top().first;
        nodac=cod_normal.top().second;
        cod_normal.pop();

        if (cost[nod_ini][nodac]<costac)
         continue;

        vecini=graf_ini[nodac].size();

        for (i=0;i<vecini;i++)
        {
            nodnou=graf_ini[nodac][i].first;
            costnou=graf_ini[nodac][i].second;

            if (costnou+costac<cost[nod_ini][nodnou])
            {
                cost[nod_ini][nodnou]=costnou+costac;
                cod_normal.push(make_pair(costnou+costac,nodnou));
            }
        }
    }

}

void dijkstra_prieteni() /// pt graful de prieteni
{
    int i,nodac,confac,costac,vecini,nodnou,costnou,copieconf;
    dp[1][1]=0;
    cod_minim.push(make_pair(0,make_pair(1,1)));

    while (!cod_minim.empty())
    {
        costac=cod_minim.top().first;
        nodac=cod_minim.top().second.first;
        confac=cod_minim.top().second.second;
        copieconf=confac;
        cod_minim.pop();
        //g<<costac<<" "<<nodac<<" "<<confac<<'\n';

        vecini=graf_min[nodac].size();

        for (i=0;i<vecini;i++)
        {
            confac=copieconf;
            nodnou=graf_min[nodac][i].first;
            costnou=graf_min[nodac][i].second;
            //g<<nodac<<">"<<nodnou<<" "<<confac<<" ";
            confac=( (confac) | (1<<(nodnou-1)) );
            //g<<confac<<'\n';

            if (costnou+costac<dp[nodnou][confac])
            {
                dp[nodnou][confac]=costnou+costac;
                cod_minim.push(make_pair(costnou+costac,make_pair(nodnou,confac)));

                //g<<costnou+costac<<" "<<nodac<<">"<<nodnou<<" "<<confac<<'\n';
            }
        }

    }
}

int main()
{
  int i,j,x,y,costac,nrfriends=0;

  f>>n>>m;

  for (i=1;i<=n;i++)
    for (j=1;j<=n;j++)
     cost[i][j]=INT_MAX;

   f>>k;
   for (i=1;i<=k;i++)
   {
     f>>x;
     stops[x]=i+1;
     prieteni[i]=x;
   }

   for (i=1;i<=k+2;i++)
    for (j=0;j<=logmax;j++)
     dp[i][j]=INT_MAX;

   stops[1]=1;
   stops[n]=k+2;

   for (i=1;i<=m;i++)
   {
     f>>x>>y>>costac;
     graf_ini[x].push_back(make_pair(y,costac));
     graf_ini[y].push_back(make_pair(x,costac));
   }

   dijkstra_normal(1);
   dijkstra_normal(n);

   for (i=1;i<=k;i++)
    dijkstra_normal(prieteni[i]);

   for (i=1;i<=n;i++)
   {
       if (stops[i])
       {
           for (j=1;j<=n;j++)
            if (stops[j] && i!=j)
             graf_min[stops[i]].push_back(make_pair(stops[j],cost[i][j]));
       }
   }

   dijkstra_prieteni();

   g<<dp[k+2][(1<<(k+2))-1];


   return 0;
}