Pagini recente » Cod sursa (job #1282675) | Cod sursa (job #701552) | Cod sursa (job #1418035) | Cod sursa (job #2803942) | Cod sursa (job #997724)
Cod sursa(job #997724)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <bitset>
#include <cstring>
FILE *f=fopen("ubuntzei.in","r");
FILE *g=fopen("ubuntzei.out","w");
using namespace std;
const int INF = 0x3f3f3f3f;
const int Nmax = 2005,Mmax=10005,Kmax=17;
int N,M,K,v[Kmax+10];
int C[(1<<Kmax)+10][Kmax],cost[Kmax+10][Kmax+10];
int D[Kmax][Nmax];
bitset<Nmax>used[Kmax+10];
vector<int>G[Kmax+10];
vector<pair<int,int> > lv[Nmax];
void get_graph()
{
fscanf(f,"%d%d%d",&N,&M,&K);
v[1]=1;//bagam si nodul de start in lista oraselor prin care trecem
v[++K+1]=N;
for(int i=2;i<=K;++i)fscanf(f,"%d",&v[i]);//cele k localitati prin care tre sa trec
++K;
sort(v+1,v+K+1);
int a,b,c;
for(int i=1;i<=M;++i)
{
fscanf(f,"%d%d%d",&a,&b,&c);
lv[a].push_back(make_pair(b,c));
lv[b].push_back(make_pair(a,c));
}
}
struct cmp{
bool operator()(const pair<int,int> A,const pair<int,int> B)const
{
return A.second > B.second;
}
};
void bellman_ford(int nodc,int lvl)
{
queue<int> Q;
vector<pair<int,int> > ::iterator it;
D[lvl][nodc]=0;
Q.push(nodc);
while(!Q.empty())
{
nodc=Q.front();
Q.pop();
for(it=lv[nodc].begin();it!=lv[nodc].end();++it)
if(D[lvl][it->first] > D[lvl][nodc] + it->second)
{
D[lvl][it->first] = D[lvl][nodc] + it->second;
Q.push(it->first);
}
}
}
void make_newgraph()// aici creeam noul graf ( complet ) in care
{ //trebuie sa determinam LANTUL hamiltonian de cost minim
memset(cost,INF,sizeof(cost));
for(int i=0;i<K;++i)
for(int j=i+1;j<K;++j)
if(i!=j)
{
G[j].push_back(i);
G[i].push_back(j);
cost[i][j]=cost[j][i]=D[i+1][v[j+1]];
}
}
void solve()
{
memset(C,INF,sizeof(C));
int i,j;
vector<int> :: iterator it;
C[1][0]=0;//starea initiala C[i][j] - costul minim al unui
//lanti H care trece prin nodurile din maska I si se termina in J
for(i = 1; i < (1 << K) ; ++i) // luam toate mastile
for(j = 0; j < K; ++j) // luam toate nodurile
if( i & (1<<j) )// daca nodul j apare in maska
for(it=G[j].begin(); it !=G[j].end();++it)//luam toti vecinii lui J
if(i & (1<<(*it)))//daca vecinul apare si el in maska , presupunem ca venim din el si optimizam
C[i][j]=min(C[i][j], C[i ^ (1<<j)][*it] + cost[*it][j]);// optim daca se poate
int answer=C[(1<<K)-1][K-1];//in alte cuvinte , raspunsul se afla in maska completa si pe pozitia K-1 adica ultimul nod din V
fprintf(g,"%d",answer);
}
int main()
{
get_graph();
memset(D,INF,sizeof(D));
for(int i=1;i<=K;++i)
bellman_ford(v[i],i);//dijkstra(v[i],i);
make_newgraph();
solve();
return 0;
}