/**********************************************************************/ |2011-06-10 14:58:51 Accepted 2066 15MS 4220K 2307 B C++ | 题意:求一个含多个源点多个汇点的多源多汇最短路问题,直接加一个超级源点 | 和超级汇点即可, 不过要小心找最大节点时一定要找准哦,不然,哼哼…… /**********************************************************************/ #include<iostream> #include<queue> #include<vector> #include<algorithm> using namespace std; #define min(a, b) (a<b ? a:b) #define max(a, b) (a>b ? a:b) #define max_three(a, b, c) (a>max(b,c) ? a:max(b,c)) const int INF = 9999999; const int maxn = 1003; int g[maxn][maxn]; int dis[maxn]; int vis[maxn]; struct node { int t, w; node(int tt, int ww) : t(tt), w(ww){} bool operator < (const node &qnode) const { return w > qnode.w; } }; vector<int>edges[maxn]; //初始化数据 void init() { memset(dis, INF, sizeof(dis)); memset(vis, 0, sizeof(vis)); for(int i=0; i<maxn; i++) { edges[i].clear(); for(int j=0; j<maxn; j++) { if(i!=j) g[i][j] = 99999999; } } } //BellmanFord算法算法 void SPFA(int src) { priority_queue<node>Q; dis[src] = 0; Q.push(node(src, 0)); while(!Q.empty()) { node curnode = Q.top(); Q.pop(); int u = curnode.t; if(vis[u]==1) continue; vis[u] = 1; for(unsigned int i=0; i<edges[u].size(); i++) { int v = edges[u][i]; if(!vis[v] && dis[v] > dis[u] + g[u][v]) { dis[v] = dis[u] + g[u][v]; Q.push(node(v, dis[v])); } } } } int main() { int E, S, D, i; while(scanf("%d%d%d", &E, &S, &D)!=EOF) { init(); int f, t, w, max_node = 0; for(i=0; i<E; i++) { scanf("%d%d%d", &f, &t, &w); edges[f].push_back(t); edges[t].push_back(f); g[f][t] = min(w, g[f][t]); g[t][f] = g[f][t]; max_node = max_three(max_node, f, t); } for(i=0; i<S; i++) { scanf("%d", &f); edges[0].push_back(f); edges[f].push_back(0); g[0][f] = 0; g[f][0] = g[0][f]; } max_node += 1; for(i=0; i<D; i++) { scanf("%d", &t); edges[t].push_back(max_node); edges[max_node].push_back(t); g[t][max_node] = 0; g[max_node][t] = g[t][max_node]; } SPFA(0); printf("%d/n", dis[max_node]); } return 0; }