[欧拉回路][并查集] Bzoj P3706 反色刷

 

Description

给一张无向图,边有黑白两种颜色,现在你有一堆反色刷,可以从任意点开始刷,经过若干条边后回到起点。
现在要询问至少需要多少个反色刷可以使这张图所有边都变成白色。
因为某种原因,边的颜色是会改变的,于是。。
需要支持以下操作:
1 x  把第x条边反色(编号从0~m-1)
2   询问当前图中最少需要多少个反色刷

Input

第一行两个整数n m表示这张图有n个点m条边
接下来m行 每行3个整数 u v c表示一条无向边和这条边的颜色(0为白色 1为黑色)
接下来一个整数q 表示有q个操作
接下来q行为操作 描述如上

Output

对于每个询问 输出一行一个整数
表示最少需要的反色刷个数 如果没有合法方案输出-1

Sample Input

6 6
1 2 1
2 3 1
1 3 1
4 5 1
5 6 1
4 6 1
14
2
1 0
2
1 1
1 2
2
1 3
1 4
1 5
2
1 3
1 4
1 5
2

Sample Output

2
-1
1
0
1

Hint

100%  n,m,q <= 1000000, c < 2,没有重边自环

 

 

题解

  • 首先题目有解当且仅当每个点连接的黑边数量均为偶数
  • 若有解答案就等于存在黑边的连通块数量
  • 证明:对于一个连通块,假设当前选择了两条分别从u和v开始的不相交的路径
  • 我们可以通过先走u为起点的路径,然后从u走到v,再走从v开始的路径
  • 最后回到u来将这两条路径合并

代码

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int N=1000005;
 6 int n,m,cnt,now,q,f[N],d[N],col[N];
 7 struct edge{int x,y,c;}e[N];
 8 int find(int x) { return f[x]==x?x:f[x]=find(f[x]); }
 9 int main()
10 {
11     scanf("%d%d",&n,&m);
12     for (int i=1;i<=n;i++) f[i]=i;
13     for (int i=1,x,y,z;i<=m;i++)
14     {
15         scanf("%d%d%d",&x,&y,&z),e[i].x=x,e[i].y=y,e[i].c=z;
16         if (z) now-=d[x]+d[y],d[x]^=1,d[y]^=1,now+=d[x]+d[y];
17         if (find(x)!=find(y)) f[find(x)]=find(y);
18     }
19     for (int i=1;i<=m;i++)
20         if (e[i].c)
21         {
22             int x=find(e[i].x);
23             if (!col[x]) cnt++;
24             col[x]++;
25         }
26     scanf("%d",&q);
27     for (int op,x;q;q--)
28     {
29         scanf("%d",&op);
30         if (op==2) printf("%d\n",now?-1:cnt);
31         else
32         {
33             scanf("%d",&x),x++;
34             now-=d[e[x].x]+d[e[x].y],d[e[x].x]^=1;d[e[x].y]^=1,now+=d[e[x].x]+d[e[x].y];
35             if (e[x].c)
36             {
37                 e[x].c=0,col[find(e[x].x)]--;
38                 if (!col[find(e[x].x)]) cnt--;
39             }
40             else
41             {
42                 e[x].c=1;
43                 if (!col[find(e[x].x)]) cnt++;
44                 col[find(e[x].x)]++;
45             }
46         }
47     }
48     return 0;
49 } 

 

posted @ 2019-07-07 10:03  BEYang_Z  阅读(338)  评论(0编辑  收藏  举报