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\n",tx);
85         return 0;
86     }
87     puts("Possible");
88     printf("0\n");
89     for(i = 1; i < n ; i++)
90     {
91         int ff = find(i);
92         printf("%lld\n",r[i]+mm[ff]);
93     }
94     return 0;
95 }
View Code

 

posted @ 2013-10-01 17:05  _雨  阅读(336)  评论(0编辑  收藏  举报