专栏文章

P10777

P10777题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minoz72t
此快照首次捕获于
2025/12/02 05:59
3 个月前
此快照最后确认于
2025/12/02 05:59
3 个月前
查看原文
考虑单个连通块,容易发现只要它不存在欧拉回路,就一定无解。
这是因为,如果一个连通块有若干个存在欧拉回路的子图,则它们一定呈环状。假设原图无欧拉回路,那么这些子图一定由一些链串联起来,这些链就导致原图一定是无解的。如果一个连通块连一个这样的子图都没有,那更不用说。
考虑多个连通块的情形,我们发现只要有一个连通块无解整个图就无解。否则,若连通块不是孤点(即存在黑边)贡献为 11,反之为 00
于是,我们使用并查集维护连通块的黑边数量,并在此过程中顺便维护贡献。同时对于有解性判断,我们仅需记录每个节点的度数奇偶性,然后维护度数之和,只要为 00 就有解。
实现CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N=1e6+5;
int n,m,q,cnt,tot;
int d[N],fa[N],black[N];
struct EDGE{
	int u,v,c;
}e[N];

int fnd(int x){
	return fa[x]==x?x:fa[x]=fnd(fa[x]);
}
void mrg(int x,int y){
	x=fnd(x),y=fnd(y);
	if(x!=y)
		fa[x]=y;
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	int ok=0;
	for(int i=1,u,v,c;i<=m;i++){
		cin>>u>>v>>c;
		e[++tot]={u,v,c};
		if(c){
			ok-=d[u]+d[v];
			d[u]^=1,d[v]^=1;
			ok+=d[u]+d[v];
		}
		mrg(u,v);
	}
	for(int i=1;i<=m;i++){
		if(e[i].c){
			int u=fnd(e[i].u);
			if(!black[u])
				cnt++;
			black[u]++;
		}
	}
	cin>>q;
	while(q--){
		int op,x;
		cin>>op;
		if(op==1){
			cin>>x,x++;
			ok-=d[e[x].u]+d[e[x].v];
			d[e[x].u]^=1,d[e[x].v]^=1;
			ok+=d[e[x].u]+d[e[x].v];
			if(e[x].c){
				e[x].c=0;
				black[fnd(e[x].u)]--;
				if(!black[fnd(e[x].u)])
					cnt--;
			}
			else{
				e[x].c=1;
				if(!black[fnd(e[x].u)])
					cnt++;
				black[fnd(e[x].u)]++;
			}
		}
		else
			cout<<(ok?-1:cnt)<<'\n';
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...