HFUT-1360 单身晚会 【SPFA】

Description

 

​ZJ和ZCX在一起很久了,两个人都互生爱意,最终决定喜结良缘,从此踏入浪漫的婚姻殿堂。

但是,ZJ的好基友们想到以后ZJ就不能经常跟他们一起愉快的玩耍了,都觉得非常伤心难过,于是他们决定在最后一晚为ZJ开一场单身晚会,玩整晚紧张刺激的飞行棋。

ZJ的好基友居住在城市的各个地方(每个地方不一定只有一个基友),他们需要从各个地方赶到其中一个朋友的家里来参加这最后的单身PARTY,ZJ被基友们的热情深深感动了,决定对基友们来时的路费进行报销。报销规则按照距离来计算。基友们为了帮ZJ省钱,决定在所有人走最短路径的情况下,总距离最小的人的家里开PARTY。

ZJ想知道基友们走过的总距离是多少,然后他把总共需要报销的钱拿出来,就可以让基友们自己来分配了。但是他算了半天也没算出来总距离是多少,单身PARTY马上就开始了,你能帮帮他吗?


 

Input

 

第一行一个整数T,表示有T(T<15)组数据

每组数据的第一行基友数(包括ZJ)N(N<100),路口P(2<=P<=100),路口之间道路数C(1<=C<=1450),(基友的编号为1…N,路口的编号为1…P)

第二行到第N+1行:编号为1到N的基友们家所在的路口号。

第N+2行到N+C+1行:每行有三个数:相连的路口A,B,路口间间距D(1<=D<=255),当然,连接是双向的。

 

Output

 

每组数据输出占一行,输出大家必须要走的最小距离和

 

Sample Input

 

1
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5

 

Sample Output

 

8
 
 
题解:
 
去年省赛的一道图论题,裸的最短路,直接枚举每个路口跑spfa或者dij。
 
 
代码:
 
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define INF 0x3f3f3f3f
 4 #define M(a, b) memset(a, b, sizeof(a))
 5 const int N = 100 + 5;
 6 int d[N], p[N], cnt[N], inq[N], n;
 7 struct Node {
 8     int to, w;
 9 };
10 vector<Node> G[N];
11 
12 queue<int> q;
13 void spfa(int s) {
14     M(d, INF); M(inq, 0);
15     while (!q.empty()) q.pop();
16     q.push(s); inq[s] = 1; d[s] = 0;
17     while (!q.empty()) {
18         int u = q.front(); q.pop();
19         inq[u] = 0;
20         for (int i = 0; i < G[u].size(); ++i) {
21             int v = G[u][i].to, w = G[u][i].w;
22             if (d[v] > d[u] + w) {
23                 d[v] = d[u] + w;
24                 if (inq[v]) continue;
25                 inq[v] = 1;
26                 q.push(v);
27             }
28         }
29     }
30 }
31 
32 int main() {
33     int m, c, T;
34     scanf("%d", &T);
35     while (T--) {
36         scanf("%d%d%d", &n, &m, &c);
37         for (int i = 1; i <= m; ++i) G[i].clear();
38         for (int i = 1; i <= n; ++i) scanf("%d", &p[i]);
39         int u, v, w;
40         for (int i = 1; i <= c; ++i) {
41             scanf("%d%d%d", &u, &v, &w);
42             G[u].push_back(Node{v, w});
43             G[v].push_back(Node{u, w});
44         }
45         int ans = INF;
46         for (int i = 1; i <= m; ++i) {
47             spfa(i);
48             int temp = 0;
49             for (int j = 1; j <= n; ++j) {
50                 temp += d[p[j]];
51             }
52             ans = min(ans, temp);
53         }
54         printf("%d\n", ans);
55     }
56 
57 
58     return 0;
59 }

 

 

转载于:https://www.cnblogs.com/robin1998/p/6718458.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值