uva 10246(变形floyd)

这道题是world finals的热身赛第一题。弱菜花了两个小时在做出来-。-

题意:给你一张无向图,然后给若干个查询,问你任意两个定点之间的最短路。最短路的定义是这样的:每个定点有权值,每个边也有权值,最短路等于路径上的所有边权值之和+所有定点的权值最大值。

思路:这道题先分析一下测试数据,顶点最多只有80个边最多有1000条所以一定是有重边的,这道题又要用邻接矩阵存所以输入的时候注意一下就好了,然后看查询有6000+个所以还是会有很多重复的,因此我们就可以想到用floyd来做这道题了。那么定点的权值怎么处理呢?我们想到了floyd的dp过程是按定点顺序的,所以我们将顶点按照花费排个序,这样有序的dp就能解出答案了。

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <algorithm>
 7 #include <queue>
 8 #include <stack>
 9 #include <vector>
10 #define MP(a, b) make_pair(a, b)
11 #define PB(a) push_back(a)
12 
13 using namespace std;
14 
15 typedef long long ll;
16 typedef pair<int ,int> pii;
17 typedef pair<unsigned int, unsigned int> puu;
18 typedef pair<int ,double> pid;
19 typedef pair<ll, int> pli;
20 
21 const int INF = 0x3f3f3f3f;
22 const double eps = 1e-6;
23 const int LEN = 101;
24 struct V{int tag, val;};
25 int Map[LEN][LEN], dis[LEN][LEN][LEN], n, m;
26 V vex[LEN];
27 inline bool cmp(V a, V b){return a.val<b.val;}
28 
29 void floyd()
30 {
31     for(int i=1; i<=n; i++){
32         for(int j=1; j<=n; j++){
33             dis[i][j][0] = Map[i][j];
34             if(i==j)dis[i][j][0] = 0;
35         }
36     }
37     for(int x=1; x<=n; x++){
38         int k = vex[x].tag;
39         for(int i=1; i<=n; i++){
40             for(int j=1; j<=n; j++){
41                 dis[i][j][x] = min(dis[i][j][x-1], dis[i][k][x-1]+dis[k][j][x-1]);
42             }
43         }
44     }
45 }
46 
47 int main()
48 {
49 //    freopen("in.txt", "r", stdin);
50 
51     int q, kase = 1, tval, a, b;
52     while(scanf("%d%d%d", &n, &m, &q)!=EOF){
53         if(!n && !m && !q)break;
54         if(kase!=1)printf("
");
55         memset(dis, 0x3f, sizeof dis);
56         memset(Map, 0x3f, sizeof Map);
57         for(int i=1; i<=n; i++){
58             vex[i].tag = i;
59             scanf("%d", &vex[i].val);
60         }
61         for(int i=0; i<m; i++){
62             scanf("%d%d%d", &a, &b, &tval);
63             Map[a][b] = min(Map[a][b], tval);
64             Map[b][a] = min(Map[b][a], tval);
65         }
66         sort(vex+1, vex+n+1, cmp);
67         floyd();
68         printf("Case #%d
", kase++);
69         for(int i=0; i<q; i++){
70             scanf("%d%d", &a, &b);
71             int ans = INF, inv = 0;
72             for(int j=1; j<=n; j++)if(vex[j].tag==a || vex[j].tag==b)inv = max(inv, vex[j].val);
73             for(int j=1; j<=n; j++){
74                 ans = min(ans, dis[a][b][j]+max(vex[j].val, inv));
75             }
76             if(ans!=INF)printf("%d
", ans);
77             else printf("-1
");
78         }
79     }
80     return 0;
81 }
View Code
奔跑吧!少年!趁着你还年轻
原文地址:https://www.cnblogs.com/shu-xiaohao/p/3515142.html