poj2395 Out of Hay

题意就是给你一张无向连通图,试问对于图上所有点对(u,v)从u到v的所有路径中边权最大值的最小值的最大值。

定义f(u,v)表示从u到v所有路径中边权最大值的最小值,对所有点对取其最大。

实际上就是求图G的最小生成树的最大边权。

考虑kruskal算法流程,每次选取边权最小的且不产生圈的边加入mst。

至算法结束,图恰好连通,并且选取的边权都是最小的。

对于那些产生回路的边加入到mst中是没有意义的,因为之前保持图连通时选取的边权更小。

注意考虑重边。

 

http://poj.org/problem?id=2395

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <map>
 5 #include <queue>
 6 using namespace std;
 7 typedef __int64 LL;
 8 const int maxn = 2e3 + 10;
 9 const int maxm = 1e4 + 10;
10 const int inf = 1e9 + 1e8;
11 struct Edge{
12     int from, to, next, c;
13     bool operator < (const Edge& rhs) const{
14         return c < rhs.c;
15     }
16 }edge[maxm << 1];
17 struct Point{
18     int x, y, c;
19     bool operator < (const Point& rhs) const{
20         return x < rhs.x || (x == rhs.x && y < rhs.y) || (x == rhs.x && y == rhs.y && c < rhs.c);
21     }
22 };
23 int head[maxn], N;
24 Point a[maxm];
25 int n, m, k;
26 int ans;
27 bool vis[maxn];
28 
29 void addEdge(int u, int v, int c){
30     edge[N].next = head[u];
31     edge[N].from = u;
32     edge[N].to = v;
33     edge[N].c = c;
34     head[u] = N++;
35 }
36 
37 int fa[maxn];
38 
39 int find(int u){
40     if(fa[u] == -1 || fa[u] == u) return u;
41     return fa[u] = find(fa[u]);
42 }
43 int main(){
44     //freopen("in.txt", "r", stdin);
45     while(~scanf("%d%d", &n, &m)){
46         N = 0;
47         memset(head, -1, sizeof head);
48         for(int i = 0; i < m; i++){
49             scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].c);
50             if(a[i].x > a[i].y) swap(a[i].x, a[i].y);
51         }
52         sort(a, a + m);
53         k = 0;
54         for(int i = 0; i < m; i++){
55             a[k++] = a[i];
56             while(i < m - 1 && a[i].x == a[i + 1].x && a[i].y == a[i + 1].y) ++i;
57         }
58         for(int i = 0; i < k; i++) addEdge(a[i].x, a[i].y, a[i].c);
59         sort(edge, edge + N);
60         int ans = -1;
61         memset(fa, -1, sizeof fa);
62         for(int i = 0; i < N; i++){
63             int u = edge[i].from, v = edge[i].to;
64             int fu = find(u), fv = find(v);
65             if(fu != fv) fa[fv] = fu, ans = max(ans, edge[i].c);
66         }
67         printf("%d\n", ans);
68     }
69     return 0;
70 }
View Code

 

转载于:https://www.cnblogs.com/astoninfer/p/4843982.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值