[Euler] [disjoint-set] Bzoj P3706 reverse color brush

 

Description

To an undirected graph, while white and black colors, now you have a bunch of anti-color brush, brush can start from any point, after several sides back to the beginning.
Now to ask how many anti-color brush can at least make this picture all the edges are white.
For some reason, the edge color will change, so. .
We need to support the following:
. 1 x x sides of the article in reverse color (m-numbered. 1 ~ 0)
2 querying the current drawing color requires a minimum number of counter-brush

Input

The first two rows represent integers nm This map contains n points m edges
next m lines each uvc represents an integer of 3 undirected edges and the color of this edge (0 to 1 white black)
Next, a q q represents an integer of operations has
the following operation described above behavior q

Output

For each line a query output integer
represents the minimum required number of brush reverse color scheme output if no valid -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, no multiple edges loopback

 

 

answer

  • First Title solvable if and only if the number of black bars are connected to each point of an even number
  • The number of black bars if the communication blocks is equal to text answer is present
  • Proof: For a communication block, assumed that the current paths respectively selected from two start u and v disjoint
  • We can u go through as a starting point of the path, and then walked v from u, v path from the beginning of the walk
  • And finally back to u to merge these two paths

Code

 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 } 

 

Guess you like

Origin www.cnblogs.com/Comfortable/p/11145176.html