对于一个连通块,如果不存在黑边度数为奇数的点,那么一定可以把所有边都刷成白色。

证明,我们提出所有的黑边,构成一些连通块,这些点的度数都是偶数,通过欧拉回路即证。

接着我们证明对于每一个这样的连通块,我们总可以一次刷完。

上面证明了对于每一个黑边连通块,我们都可以一次刷完。在原图的一个连通块中,对于两个黑边连通块,我们都可以找到一条路径走过去,然后再走回来。所以我们一定可以一次刷完。

接下来就是简单统计。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6;
int n,m,q;
int U[maxn+5],V[maxn+5],W[maxn+5];
int fa[maxn+5];
int dg[maxn+5];
int cnt[maxn+5];
int ans,tot;
int Root(int u){
if(fa[u]) return fa[u]=Root(fa[u]);
else return u;
}
inline void Solve(int u,int v){
if(dg[u]){
if(v>0) ans+=!cnt[Root(u)];
cnt[Root(u)]+=v;
if(v<0) ans-=!cnt[Root(u)];
}
if(dg[u]&1) tot+=v;
}
signed main(){
int u,v,w;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&w);
U[i]=u,V[i]=v,W[i]=w;
dg[u]+=w,dg[v]+=w;
u=Root(u),v=Root(v);
if(u==v) continue;
fa[u]=v;
}
for(int i=1;i<=n;i++) Solve(i,+1);
int op,x;
scanf("%d",&q);
while(q--){
scanf("%d",&op);
if(op==1){
scanf("%d",&x);
u=U[x],v=V[x],w=W[x];
W[x]^=1;
Solve(u,-1),Solve(v,-1);
if(w) dg[u]--,dg[v]--;
else dg[u]++,dg[v]++;
Solve(u,+1),Solve(v,+1);
}
else{
if(tot) puts("-1");
else printf("%d\n",ans);
}
}
return 0;
}