题意:求多个源点单个汇点的最短路。
1000个点,很明显floyd会爆,用dijkstra和bellman ford\spfa应该都行把。。。
网上大神说了两种思路:
1.新建一个超级源点,和各个源点的距离为0,就跟网络流的超级源点。
2.反向从终点进行最短路算法。
都是很巧妙的办法,如果遇到多汇点的话,就可以弄个超级汇点就行了。
代码:
/*
* Author: illuz <iilluzen[at]gmail.com>
* Blog: http://blog.csdn.net/hcbbt
* File: hdu2680.cpp
* Create Date: 2013-11-28 18:55:39
* Descripton: dijkstra
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1010;
const int INF = 0x3c3c3c3c - 1;
int nn, en;
int m[MAXN][MAXN], dis[MAXN];
bool vis[MAXN];
int dijkstra(int op, int ed) {
memset(vis, false, sizeof(vis));
for (int i = 1; i <= nn; i++)
dis[i] = m[op][i];
dis[op] = 0;
vis[op] = true;
for (int i = 1; i <= nn; i++) {
int t = INF, k;
for (int j = 1; j <= nn; j++)
if (!vis[j] && t > dis[j])
t = dis[j], k = j;
if (t == INF) break;
vis[k] = true;
for (int j = 1; j <= nn; j++)
if (!vis[j])
dis[j] = min(dis[j] , dis[k] + m[k][j]);
}
return dis[ed];
}
int main() {
int op, ed, t, d, w;
while (~scanf("%d%d%d", &nn, &en, &d)) {
// init
for (int i = 1; i <= nn + 1; i++)
for (int j = 1; j <= nn + 1; j++)
m[i][j] = INF;
for (int i = 1; i <= en; i++) {
scanf("%d%d%d", &op, &ed, &t);
if (t < m[op][ed])
m[op][ed] = t;
}
nn++;
scanf("%d", &w);
for (int i = 1; i <= w; i++) {
scanf("%d", &t);
m[nn][t] = 0;
}
int ans = dijkstra(nn, d);
printf("%d\n", ans != INF ? ans : -1);
}
return 0;
}