• 1701. Ostap and Partners(并查集-关系)


    1701

    又是类似食物链的这一类题 

    这题是找与根节点的和差关系 因为0节点是已知的 为0  那么所有的都可以转换为与0的和差关系 

    可以规定合并的两节点 由大的指向小的 然后再更新和差关系 

    有可能最后有的不在0集合中 这时要确定最大初值 当然根据集合中出现的负值来确定 题目中工资不能出现负值 也不可大于10^9 在处理完关系后 再判断一下这两个条件 不满足的话就输出m

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 using namespace std;
     8 #define N 50010
     9 #define LL long long
    10 #define maxz 1000000000
    11 int n,m;
    12 int f[N];
    13 LL r[N],mm[N];
    14 int find(int x)
    15 {
    16     if(x!=f[x])
    17     {
    18         int o = f[x];
    19         f[x] = find(f[x]);
    20         r[x] += r[o];
    21     }
    22     return f[x];
    23 }
    24 int main()
    25 {
    26     int i,a,b,c;
    27     int flag = 0,tx = maxz;
    28     scanf("%d%d",&n,&m);
    29     for(i = 0 ; i < n ; i++)
    30     {
    31         f[i] = i;
    32         r[i] = 0;
    33     }
    34     for(i = 1 ;i <= m ; i++)
    35     {
    36         scanf("%d%d%d",&a,&b,&c);
    37         if(flag)
    38         continue;
    39         int x = find(a),y = find(b);
    40         if(x!=y)
    41         {
    42             if(x<y)
    43             {
    44                 swap(x,y);
    45                 swap(a,b);
    46                 c = -c;
    47             }
    48             f[x] = y;
    49             r[x] = -r[a]+r[b]+c;
    50         }
    51         else
    52         {
    53             if(r[a]-r[b]!=c)
    54             {
    55                 flag = 1;
    56                 tx = i;
    57 
    58             }
    59         }
    60     }
    61     for(i = 1; i < n ; i++)
    62     {
    63         int ho = find(i);
    64         if(ho!=0)
    65         {
    66             if(r[i]<0)
    67             {
    68                 mm[ho] = max(mm[ho],-r[i]);
    69             }
    70         }
    71     }
    72     for(i = 1 ; i < n ; i++)
    73     {
    74         int ff = find(i);
    75         if((r[i]+mm[ff])>maxz||(r[i]+mm[ff])<0)
    76         {
    77             flag = 1;
    78             tx = m;
    79             break;
    80         }
    81     }
    82     if(flag)
    83     {
    84         printf("Impossible after %d statements
    ",tx);
    85         return 0;
    86     }
    87     puts("Possible");
    88     printf("0
    ");
    89     for(i = 1; i < n ; i++)
    90     {
    91         int ff = find(i);
    92         printf("%lld
    ",r[i]+mm[ff]);
    93     }
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    你必须知道的495个C语言问题,学习体会四
    ++操作符重载代码分析
    正斜杠 与反斜杠之争
    文件操作基础入门
    你必须知道的495个C语言问题,学习体会三
    你必须知道的495个C语言问题,学习体会二
    【皇甫】☀别进来 千万别进来
    【皇甫】☀设计_模式
    【皇甫】☀七个小矮人和一个小博
    【皇甫】☀游戏还有游戏还是游戏
  • 原文地址:https://www.cnblogs.com/shangyu/p/3348629.html
Copyright © 2020-2023  润新知