Pagini recente » Cod sursa (job #715938) | Cod sursa (job #1683141) | Cod sursa (job #2000533) | Cod sursa (job #3244568) | Cod sursa (job #176889)
Cod sursa(job #176889)
// Team, Infoarena/Lot 2006
// http://infoarena.ro/problema/team
#define _CRT_SECURE_NO_DEPRECATE
#include <cstdio>
#include <cstring>
#include <climits>
#include <list>
#include <set>
using namespace std;
const int NMAX = 512;
const int PMAX = 64;
int p, n, m;
list<pair<int, int> > Neighb[NMAX];
int Dist[NMAX][NMAX], Ans[PMAX][PMAX][NMAX];
int End[PMAX], Used[NMAX];
set<int> Cities;
/*void roy_floyd() {
int k, i, j;
for (k = 1; k <= n; ++ k)
for (i = 1; i <= n; ++ i) {
if (k == i)
continue;
for (j = 1; j <= n; ++ j) {
if (Dist[i][k] == INT_MAX || Dist[k][j] == INT_MAX)
continue;
if (Dist[i][j] > Dist[i][k] + Dist[k][j])
Dist[i][j] = Dist[i][k] + Dist[k][j];
}
}
}*/
void dijkstra(int src) {
int i, j, curr, next, ans;
list<pair<int, int> >::iterator li;
memset(Used, false, sizeof(Used));
Used[src] = true;
curr = src;
for (i = 1; i <= n; ++ i) {
for (li = Neighb[curr].begin(); li != Neighb[curr].end(); ++ li)
if (Dist[src][li->first] > Dist[src][curr] + li->second)
Dist[src][li->first] = Dist[src][curr] + li->second;
ans = INT_MAX;
for (j = 1; j <= n; ++ j)
if (Used[j] == false && ans > Dist[src][j]) {
ans = Dist[src][j];
curr = j;
}
}
}
int main() {
freopen("team.in", "r", stdin);
freopen("team.out", "w", stdout);
scanf("%d %d %d", &p, &n, &m);
int i, j, v1, v2, c;
for (i = 1; i <= n; ++ i)
for (j = 1; j <= n; ++ j)
Dist[i][j] = INT_MAX;
for (i = 1; i <= n; ++ i)
Dist[i][i] = 0;
for (i = 0; i < m; ++ i) {
scanf("%d %d %d", &v1, &v2, &c);
Neighb[v1].push_back(make_pair(v2, c));
Neighb[v2].push_back(make_pair(v1, c));
//Dist[v1][v2] = Dist[v2][v1] = c;
}
for (i = 1; i <= p; ++ i) {
scanf("%d", &End[i]);
Cities.insert(End[i]);
}
Cities.insert(1);
for (i = 1; i <= n; ++ i)
dijkstra(i);
//roy_floyd();
set<int>::iterator si;
int k, l, ans;
for (l = 1; l <= p; ++ l)
for (i = 1; i <= p - l + 1; ++ i)
for (si = Cities.begin(); si != Cities.end(); ++ si)
Ans[i][i + l - 1][*si] = INT_MAX;
for (i = 1; i <= p; ++ i)
for (j = 1; j <= n; ++ j)
Ans[i][i][j] = Dist[j][End[i]];
for (l = 2; l <= p; ++ l)
for (i = 1; i <= p - l + 1; ++ i) {
j = i + l - 1;
for (si = Cities.begin(); si != Cities.end(); ++ si) {
ans = INT_MAX;
for (k = i; k <= j; ++ k) {
if (Ans[i][k - 1][End[k]] == INT_MAX || Ans[k + 1][j][End[k]] == INT_MAX || Dist[*si][End[k]] == INT_MAX)
continue;
ans = min(ans, Ans[i][k - 1][End[k]] + Ans[k + 1][j][End[k]] + Dist[*si][End[k]]);
}
Ans[i][j][*si] = ans;
}
}
printf("%d\n", Ans[1][p][1]);
return 0;
}