ZOJ 3396 Conference Call 求经过特定3点的最小生成树
来源:互联网 发布:免费外贸交流软件 编辑:程序博客网 时间:2024/06/16 02:36
//ZOJ 3396 Conference Call//题意 求经过特定3点的最小生成树//思路:枚举任何一点作为支撑点 ,特定的3点要相连必须经过共同的一点 ,求这三点到所枚举点的最短路和,取最小值即为答案#include<iostream>#include<stdio.h>#include<string.h>#include<queue>using namespace std;#define INF 50000000#define N 20005#define M 505int n, m, k;int sta[N];int head[M], num;int dis[4][M];bool vis[M], mark[M];struct Edge { int from; int to; int val; int next;} edge[N];void addedge(int from, int to, int val) { edge[num].from = from; edge[num].to = to; edge[num].val = val; edge[num].next = head[from]; head[from] = num++;}void init() { memset(head, -1, sizeof (head)); num = 0;}void spfa(int s, int index) { memset(vis, 0, sizeof (vis)); for (int i = 1; i <= m; ++i) dis[index][i] = INF; queue<int> Q; Q.push(s); dis[index][s] = 0; vis[s] = 1; while (!Q.empty()) { int p = Q.front(); Q.pop(); vis[p] = 0; for (int i = head[p]; i != -1; i = edge[i].next) { if (dis[index][edge[i].to] > dis[index][p] + edge[i].val) { dis[index][edge[i].to] = dis[index][p] + edge[i].val; if (!vis[edge[i].to]) { Q.push(edge[i].to); vis[edge[i].to] = 1; } } } }}int main() { int i, j, ca = 1; int a, b, c; while (scanf("%d %d %d", &n, &m, &k) != EOF) { init(); for (i = 1; i <= n; ++i) scanf("%d", &sta[i]); for (i = 1; i <= k; ++i) { scanf("%d %d %d", &a, &b, &c); addedge(a, b, c); addedge(b, a, c); } int bx; int qua; scanf("%d", &qua); printf("Case #%d\n", ca++); for (i = 1; i <= qua; ++i) { scanf("%d %d %d", &a, &b, &c); spfa(sta[a], 1); spfa(sta[b], 2); spfa(sta[c], 3); int ans = INF; for (j = 1; j <= m; ++j) if (dis[1][j] + dis[2][j] + dis[3][j] < ans){ ans = dis[1][j] + dis[2][j] + dis[3][j]; bx = j; } printf("Line %d: ", i); // printf("bx :%d %d %d %d\n",bx,dis[1][bx],dis[2][bx],dis[3][bx]); if (ans == INF) printf("Impossible to connect!\n"); else printf("The minimum cost for this line is %d.\n", ans); } } return 0;}