• 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
    ", ans);
    68     }
    69     return 0;
    70 }
    View Code
  • 相关阅读:
    linux 权限管理命令
    大三上学期总结
    C# 读写Excel的一些方法,Aspose.Cells.dll
    Topshelf 创建.net服务整理和安装步骤(转)
    你必须知道的.NET之特性和属性(转)
    用SQL语句删除一个数据库的所有表和所有存储过程
    System.DllNotFoundException: 无法加载 DLL“FileTracker.dll”: 动态链接库(DLL)初始化例
    关于消息队列的使用[转]
    PhpStorm使用技巧小结
    转载]C#实现获取浏览器信息
  • 原文地址:https://www.cnblogs.com/astoninfer/p/4843982.html
Copyright © 2020-2023  润新知