[欧拉回路] 「Balkan OI 2016」Acrobat

本文探讨了一个图论问题,即如何通过选取最少数量的边来调整图中所有节点的度数,使其满足特定的奇偶性约束。文中详细介绍了问题的解决思路和证明过程,并提供了一段实现该算法的C++代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们要使左边的点度数都变为偶数。考虑第一种操作,会使左边两个点的度奇偶性变化,所以问题就转化成:给出一个图,选较少的边使得每个点的度满足奇偶性的限制。
这个怎么搞呢?有一个结论:若有解,则图的任意一个生成树,只取树边中的一些边都能得到一组解。
怎么证明呢?
显然如果已知一组边是合法的解,那么这些边一定能在同一棵生成树上。
把这组解的边标为白色边。对于其他的任意一颗生成树,若白边在树上就取他,若白边不在树上,就取对应的环。(这里取相同边次数是异或的)。这样一定能构造出在这个树上的合法解。证毕。
所以随便dfs出一颗生成树从叶往根取就好了。最多选 n1 条。
对与右边,把奇点两两配对就好了。最多 n/2
还要花 n1 保证图联通。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=300005,maxe=600005;
int n,m,dL[maxn],dR[maxn],res1[maxn],res2[maxn];
int fir[maxn],nxt[maxe],son[maxe],id[maxe],tot;
bool vis[maxn];
struct data{ int x,y; } a[maxn];
void add(int x,int y,int z){
    son[++tot]=y; id[tot]=z; nxt[tot]=fir[x]; fir[x]=tot;
}
void dfs(int x,int pre,int e_id){
    vis[x]=true;
    for(int j=fir[x];j;j=nxt[j]) if(!vis[son[j]]) dfs(son[j],x,id[j]);
    if(dL[x]&1){
        res1[++res1[0]]=e_id;
        dL[x]++, dL[pre]++;
        dR[a[e_id].x]++; dR[a[e_id].y]--;
    }
}
int main(){
    freopen("hhhoj22.in","r",stdin);
    freopen("hhhoj22.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&a[i].x,&a[i].y), dL[a[i].x]++, dR[a[i].y]++;
        add(a[i].x,a[i].y,i), add(a[i].y,a[i].x,i); 
    }
    for(int i=1;i<=n;i++) if(!vis[i]){
        dfs(i,0,0);
        if(dL[0]) return printf("-1\n"),0;
    }

    dR[1]++; dR[n]++;
    for(int i=1;i<=n;i++) if(dR[i]&1) res2[++res2[0]]=i;
    if(res2[0]&1) return printf("-1\n"),0;
    printf("%d\n",res1[0]+res2[0]/2+n-1);
    for(int i=1;i<=res1[0];i++) printf("1 %d %d\n",a[res1[i]].x,a[res1[i]].y);
    for(int i=1;i<=res2[0]-1;i+=2) printf("2 %d %d\n",res2[i],res2[i+1]);
    for(int i=1;i<=n-1;i++) printf("2 %d %d\n",i,i+1);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值