zoukankan      html  css  js  c++  java
  • POJ-2377 Bad Cowtractors---最大生成树

    题目链接:

    https://vjudge.net/problem/POJ-2377

    题目大意:

    给一个图,求最大生成树权值,如果不连通输出-1

    思路:

    kruskal算法变形,sort按边从大到小排序,就可以了,或者用一个maxn-w[u][v]作为<u, v>边的权值,直接用原来的kruskal算法求出权值,然后用maxn*(n-1)-sum就为最大生成树权值

     1 #include<iostream>
     2 #include<vector>
     3 #include<queue>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdio>
     7 #include<set>
     8 #include<map>
     9 #include<cmath>
    10 using namespace std;
    11 typedef pair<int, int> Pair;
    12 typedef long long ll;
    13 const int INF = 0x3f3f3f3f;
    14 int T, n, m;
    15 const int maxn = 2e4 + 10;
    16 struct edge
    17 {
    18     int v, u, w;
    19     bool operator < (const edge a)const
    20     {
    21         return w > a.w;
    22     }
    23 };
    24 edge e[maxn];
    25 int pa[maxn];
    26 int Find(int x)
    27 {
    28     return x == pa[x] ? x : pa[x] = Find(pa[x]);//路径压缩
    29 }
    30 void kruskal()
    31 {
    32     for(int i = 1; i <= n; i++)pa[i] = i;
    33     sort(e, e + m);
    34     ll ans = 0;
    35     for(int i = 0; i < m; i++)
    36     {
    37         ll v = e[i].v, u = e[i].u, w = e[i].w;
    38         ll x = Find(v), y = Find(u);
    39         if(x != y)
    40         {
    41             pa[x] = y;
    42             ans += w;
    43         }
    44     }
    45     int tot = 0;
    46     for(int i = 1; i <= n; i++)//判断是否联通,是否只有一个父节点是自己的点
    47     {
    48         if(pa[i] == i)tot++;
    49     }
    50     if(tot > 1)cout<<"-1"<<endl;
    51     else cout<<ans<<endl;
    52 }
    53 int main()
    54 {
    55     cin >> n >> m;
    56     for(int i = 0; i < m; i++)cin >> e[i].v >> e[i].u >> e[i].w;
    57     kruskal();
    58 }
     1 #include<iostream>
     2 #include<vector>
     3 #include<queue>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdio>
     7 #include<set>
     8 #include<map>
     9 #include<cmath>
    10 using namespace std;
    11 typedef pair<int, int> Pair;
    12 typedef long long ll;
    13 const int INF = 0x3f3f3f3f;
    14 int T, n, m;
    15 const int maxn = 2e4 + 10;
    16 struct edge
    17 {
    18     int v, u, w;
    19     bool operator < (const edge a)const
    20     {
    21         return w < a.w;
    22     }
    23 };
    24 edge e[maxn];
    25 int pa[maxn];
    26 int Find(int x)
    27 {
    28     return x == pa[x] ? x : pa[x] = Find(pa[x]);//路径压缩
    29 }
    30 void kruskal()
    31 {
    32     for(int i = 1; i <= n; i++)pa[i] = i;
    33     sort(e, e + m);
    34     ll ans = 0;
    35     for(int i = 0; i < m; i++)
    36     {
    37         ll v = e[i].v, u = e[i].u, w = e[i].w;
    38         ll x = Find(v), y = Find(u);
    39         if(x != y)
    40         {
    41             pa[x] = y;
    42             ans += w;
    43         }
    44     }
    45     int tot = 0;
    46     for(int i = 1; i <= n; i++)//判断是否联通,是否只有一个父节点是自己的点
    47     {
    48         if(pa[i] == i)tot++;
    49     }
    50     ans = 100000LL * ((ll)n - 1) - ans;
    51     if(tot > 1)cout<<"-1"<<endl;
    52     else cout<<ans<<endl;
    53 }
    54 int main()
    55 {
    56     cin >> n >> m;
    57     for(int i = 0; i < m; i++)
    58     {
    59         cin >> e[i].v >> e[i].u >> e[i].w;
    60         e[i].w = 100000 - e[i].w;
    61     }
    62     kruskal();
    63 }
  • 相关阅读:
    day02_05.除数与被除数
    day02_04.算算多少人
    day02_03.五个数字一行输出
    day02_02.能被3整除的个位数为6的数
    day02_01.能被3整除的数
    day05_10 作业
    day05_09 列表内置方法
    day05_08 列表讲解、切片、内置方法
    day05_07 标志位讲解
    day05_06 continue语句、while循环
  • 原文地址:https://www.cnblogs.com/fzl194/p/8819015.html
Copyright © 2011-2022 走看看