hdu3038
题意:给定区间和判定那个说法是错误的
带权并查集需要判环
2 //主要是权值压缩类似于LA3027。
3 //注意区间左或右端点要减1
4 #include<cstring>
5 #include<cstdio>
6 #include<algorithm>
7 using namespace std;
8 const int MAX = 200000+10;
9 int pa[MAX],d[MAX],ans;
10 int make(int n)
11 {
12 for(int i=0;i<=n;i++) pa[i]=i,d[i]=0;
13 }
14 int find(int x)
15 {
16 if(pa[x]==x) return x;
17 int fx=find(pa[x]);
18 d[x]+=d[pa[x]];
19 pa[x]=fx;
20 return fx;
21 }
22 void Union(int a,int b,int w)
23 {
24 int fx=find(a);
25 int fy=find(b);
26 if(fx!=fy)
27 {
28 pa[fy]=fx;
29 d[fy]=d[a]-d[b]+w;
30 }
31 else
32 {
33 if(d[b]-d[a]!=w) ans++;
34 }
35 }
36 int main()
37 {
38 int n,m;
39 int a,b,w;
40 while(scanf("%d %d",&n,&m)>0)
41 {
42 ans=0; make(n);
43 for(int i=0;i<m;i++)
44 {
45 scanf("%d %d %d",&a,&b,&w);
46 Union(a-1,b,w);
47 }
48 printf("%d\n",ans);
49 }
50 return 0;
3 //注意区间左或右端点要减1
4 #include<cstring>
5 #include<cstdio>
6 #include<algorithm>
7 using namespace std;
8 const int MAX = 200000+10;
9 int pa[MAX],d[MAX],ans;
10 int make(int n)
11 {
12 for(int i=0;i<=n;i++) pa[i]=i,d[i]=0;
13 }
14 int find(int x)
15 {
16 if(pa[x]==x) return x;
17 int fx=find(pa[x]);
18 d[x]+=d[pa[x]];
19 pa[x]=fx;
20 return fx;
21 }
22 void Union(int a,int b,int w)
23 {
24 int fx=find(a);
25 int fy=find(b);
26 if(fx!=fy)
27 {
28 pa[fy]=fx;
29 d[fy]=d[a]-d[b]+w;
30 }
31 else
32 {
33 if(d[b]-d[a]!=w) ans++;
34 }
35 }
36 int main()
37 {
38 int n,m;
39 int a,b,w;
40 while(scanf("%d %d",&n,&m)>0)
41 {
42 ans=0; make(n);
43 for(int i=0;i<m;i++)
44 {
45 scanf("%d %d %d",&a,&b,&w);
46 Union(a-1,b,w);
47 }
48 printf("%d\n",ans);
49 }
50 return 0;
51 }
带权并查集-(第一题)
注意状态压缩时要先固定当前状态