题意:给定区间和判定那个说法是错误的
带权并查集需要判环
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 }
带权并查集-(第一题)
注意状态压缩时要先固定当前状态