题意

起点1到终点n有m条桥,每座桥都有允许最大的重量通过,现在求运输车能从1到n运输的最大重量是多少

解题思路

相当于让选择的那条路最大,然后求这条路里的最小值,而且这个值比其他路的值都大。
可用变形的dijkstra来求解,也可以用最大生成树来求解。

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
#include<vector>
#include<algorithm>
#include<cstdio>
#include<iostream>
#include<set>
#include<cstring>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,pii> PII;
const int inf = 1<<30;
const int maxn = 1e6+5;
struct Node
{
int to,val;
bool operator<(const Node& a)const
{
return val < a.val;
}
};
vector<Node> G[maxn];
int dis[maxn];

int dijkstra(int n)
{
memset(dis,-1,sizeof(dis));
int ans = inf;
priority_queue<pii> Q;
Q.push(pii(inf,1));
dis[1] = inf;
while(!Q.empty()){
pii t = Q.top();
Q.pop();
int d = t.first;
int u = t.second;
if(u==n)break;
if(dis[u] > d) continue;
for(int i=0;i<G[u].size();i++){
Node e = G[u][i];
if(dis[e.to] < min(dis[u],e.val)){
dis[e.to] = min(dis[u],e.val);
Q.push(pii(dis[e.to],e.to));
}
}
}
return dis[n];
}

int main(int argc, char const *argv[])
{
int T = 0;
int Case = 1;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)G[i].clear();
int x,y,val;
for(int i=0;i<m;i++){
scanf("%d%d%d",&x,&y,&val);
Node t;
t.to = y;
t.val = val;
G[x].push_back(t);
t.to = x;
G[y].push_back(t);
}
int ans = dijkstra(n);

printf("Scenario #%d:\n",Case++);
printf("%d\n\n",ans);
}
return 0;
}

最大生成树解法

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
#include<vector>
#include<algorithm>
#include<cstdio>
#include<iostream>
#include<set>
#include<cstring>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,pii> PII;
const int maxn = 1e6+5;
struct Node
{
int x,y,val;
bool operator<(const Node& a)const
{
return val > a.val;
}
};
Node G[maxn];
int A[maxn];
int Find(int n)
{
return n==A[n]?n:A[n]=Find(A[n]);
}

int main(int argc, char const *argv[])
{
int T = 0;
int Case = 1;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++){
A[i] = i;
}
for(int i=0;i<m;i++){
scanf("%d%d%d",&G[i].x,&G[i].y,&G[i].val);
}
sort(G,G+m);
int ans = 1<<30;
for(int i=0;i<m;i++){
int t1 = Find(G[i].x);
int t2 = Find(G[i].y);
if(t1!=t2){
if(t1>t2)swap(t1,t2);
A[t2] = t1;
if(Find(1)==Find(n)){ //最先找到让1和n连通的路径就是答案
ans = G[i].val;
break;
}
}
}
printf("Scenario #%d:\n",Case++);
printf("%d\n\n",ans);
}
return 0;
}