题意:有n个城市,m条道路,在每条道路上有一个承载量,现在要求从1到n城市最大承载量,而最大承载量就是从城市1到城市n所有通路上的最大承载量
dijkstra的变形 求最大载重量
思路:1.初始化条件和dijkstra一样,把起始节点能到到的节点更新为dis[i],起始节点到达不了的节点更新为INF,新增加一个标记数组,除1之外都标记为0,1标记为1,作用是判断该节点是否被使用过.
2.然后找与1相邻的节点中载重量最大的,记录下来节点位置和最大载重量,该节点不能被使用过。
3.遍历剩余节点,判断2中节点到达其余节点的最小值(最大输入流而且必须是map[2节点][剩余节点]存在,和dis[剩余节点比较],若大于dis,就更新dis,否则不更新.
4.再回到第二步,把之前使用过的节点扔掉,继续第三步.
大佬代码:
出处:http://poj.org/showmessage?message_id=354786
原代码最后的判断条件有误,我已修改过来.
复制代码
1
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65#include <cstdio> #include <iostream> #include <ctime> #include <cstring> #include<cstdlib> #pragma warning(disable:4996) using namespace std; #define MAX 0x7fffffff #define Min(a, b) ((a) < (b) ? (a) : (b)) int map[1010][1010], dis[1010]; int mark[1010]; int n, m, s, t, W = 0; void Dijkstra() { int i, j, k, min; for (i = 1; i <= n; i++) { mark[i] = 0; if (map[1][i] != 0) dis[i] = map[1][i]; else dis[i] = MAX; }//预处理 把1可以到达的节点全都设置成dis[i],到达不了的节点全都设置成MAX mark[1] = 1; for (i = 1; i < n; i++)//遍历除第一个节点之外的剩下的n-1个节点 { min = 0;//最大权值 for (j = 1; j <= n; j++) if (!mark[j] && dis[j] > min&&dis[j] != MAX)//从1节点引申出来的节点中的最大值 { min = dis[j]; k = j;//记录下是第几个节点权值最大 } mark[k] = 1; for (j = 1; j <= n; j++)//遍历其余的节点 if (!mark[j]) { int Q; Q = Min(dis[k], map[k][j]);//Q表示从起始节点到该节点的值和从该节点到目标节点的最小值 //Q表示走1-k-j这条路的最大限流 if ((dis[j]<Q||dis[j]==MAX)&&map[k][j] != 0)//如果最大限流大于1-j节点,且k-j有路,更新dis[j]的值 { dis[j] = Q; } } } printf("Scenario #%d:n%dnn", W, dis[n]); } int main() { int i, j, x, y, d, N; scanf("%d", &N); while (N--) { scanf("%d %d", &n, &m); W++; memset(map, 0, sizeof(map)); for (i = 1; i <= m; i++) { scanf("%d %d %d", &x, &y, &d); map[x][y] = map[y][x] = d; } Dijkstra(); } }
我的代码:
用的是优先队列去优化
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include<cmath> #include<cstdlib> #include<map> #include<string> #include<vector> #include<queue> #include<functional> #pragma warning(disable:4996) //最大边的最小权值 using namespace std; typedef long long ll; const int INF = 999999999; int n, m; typedef pair<int, int> P;//第一个值表示最大权值 struct edge { int to, cost; }; int mn; int d[1001]; vector<edge>G[1005]; int vis[1005]; void dijkstra(int s) { priority_queue<P, vector< P >, less< P > >que; for (int i = 1; i <= n; i++)d[i] = INF; memset(vis, 0, sizeof(vis)); d[s] = 0; vis[s] = 1; que.push(P(0, s)); mn = 0; while (!que.empty()) { P p = que.top(); que.pop(); int v = p.second; if (d[v] >p.first)continue; for (int i = 0; i < G[v].size(); i++) { edge e = G[v][i]; if (d[v] == 0) { d[e.to] = e.cost; que.push(P(d[e.to], e.to)); continue; } vis[v] = 1; if (!vis[e.to]) { int mn = min(d[v], e.cost); if ((mn > d[e.to] || d[e.to] == INF)) { d[e.to] = mn; que.push(P(d[e.to], e.to)); } } } } } int main() { int T; scanf("%d", &T); int i, j, k; int icase = 0; while (T--) { scanf("%d%d", &n, &m); for (i = 1; i <= n; i++)G[i].clear(); for (i = 1; i <= m; i++) { int x, y, z; scanf("%d%d%d", &x, &y, &z); edge e; e.to = x, e.cost = z; G[y].push_back(e); edge ee; ee.to = y, ee.cost = z; G[x].push_back(ee); } dijkstra(1); printf("Scenario #%d:", ++icase); printf("n"); printf("%dnn", d[n]); } }
最后
以上就是高兴火龙果最近收集整理的关于Heavy Transportation POJ - 1797的全部内容,更多相关Heavy内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复