专栏文章
P10777
P10777题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minoz72t
- 此快照首次捕获于
- 2025/12/02 05:59 3 个月前
- 此快照最后确认于
- 2025/12/02 05:59 3 个月前
考虑单个连通块,容易发现只要它不存在欧拉回路,就一定无解。
这是因为,如果一个连通块有若干个存在欧拉回路的子图,则它们一定呈环状。假设原图无欧拉回路,那么这些子图一定由一些链串联起来,这些链就导致原图一定是无解的。如果一个连通块连一个这样的子图都没有,那更不用说。
考虑多个连通块的情形,我们发现只要有一个连通块无解整个图就无解。否则,若连通块不是孤点(即存在黑边)贡献为 ,反之为 。
于是,我们使用并查集维护连通块的黑边数量,并在此过程中顺便维护贡献。同时对于有解性判断,我们仅需记录每个节点的度数奇偶性,然后维护度数之和,只要为 就有解。
实现
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 条评论,欢迎与作者交流。
正在加载评论...