Cod sursa(job #1227858)

Utilizator buzu.tudor67Tudor Buzu buzu.tudor67 Data 12 septembrie 2014 00:04:43
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.3 kb
#include<algorithm>
#include<fstream>
#include<queue>
using namespace std;
ifstream fi("ubuntzei.in");
ofstream fo("ubuntzei.out");

const int inf = 123456789;
const int max_n = 2003;
const int max_m = 10004;
const int max_k = 20;
const int max_stari = (1<<16);

vector < pair <int,int> > a[max_n];

int i,j,n,m,k,x,y,cost,mask,nr_stari,sol_min;
int C[max_k];//C[i] - localitatea celui de-al i-lea prieten
int dist[max_k][max_n];//dist[i][j] - distanta minima intre localitatile C[i] si j
int dist_1[max_n];//dist_1[i] - distanta minima intre localitatea 1 si localitatea i
int dp[max_k][max_stari];//dp[i][s] - costul minim de a ajunge in localitatea C[i] si 
                         //           sa fi trecut cel putin o data prin localitatile
                         //           din multimea s

void Bellman_Ford(const int &start_node, int dist[]){
     bool este[max_n];
     queue <int> q;
     
     for(int i=1;i<=n;i++){ dist[i]=inf; este[i]=0; }
     
     q.push(start_node);
     este[start_node]=1;
     dist[start_node]=0;
     
     while(q.size()){
                     int nod=q.front();
                     q.pop();
                     este[nod]=0;
                     
                     for(int j=0;j<(int)a[nod].size();j++)
                        {
                         int vecin=a[nod][j].first;
                         int cost=a[nod][j].second;
                         if(dist[vecin]==inf || dist[nod]+cost<dist[vecin])
                           {
                            dist[vecin]=dist[nod]+cost;
                            if(!este[vecin]){
                                             q.push(vecin);
                                             este[vecin]=1;
                                            }
                           }    
                        }
                    }
}

int main(){
    fi>>n>>m;
    
    fi>>k;
    for(i=1;i<=k;i++) fi>>C[i];
    
    for(i=1;i<=m;i++){
                      fi>>x>>y>>cost;
                      a[x].push_back(make_pair(y,cost));
                      a[y].push_back(make_pair(x,cost));
                     }
    
    Bellman_Ford(1,dist_1);
    
    if(!k) fo<<dist_1[n];
    else{
         for(i=1;i<=k;i++) Bellman_Ford(C[i],dist[i]);
         
         nr_stari=(1<<k)-1;
         for(mask=1;mask<=nr_stari;mask++)
            {
             for(j=1;j<=k;j++)
               if(mask==(1<<(j-1))){
                                    dp[j][mask]=dist_1[C[j]];
                                    break;
                                   }
                                   
             if(j<=k) continue;
             
             for(i=1;i<=k;i++)
                {               
                 dp[i][mask]=inf;
                 if(mask&(1<<(i-1)))
                   {
                    for(j=1;j<=k;j++)
                      if(i!=j && (mask&(1<<(j-1)))) 
                        dp[i][mask]=min(dp[i][mask],dp[j][mask-(1<<(i-1))]+dist[j][C[i]]); 
                   }
                }
            }
         
         mask=nr_stari;
         sol_min=inf;
         
         for(i=1;i<=k;i++)
           sol_min=min(sol_min,dp[i][mask]+dist[i][n]);
         
         fo<<sol_min;
        }
    
    fi.close();
    fo.close();
    return 0;
}