CF527E Data Center Drama

CF527E Data Center Drama

我们可以发现很明显的两条使得一个图符合条件的要求:

  1. 一个点的度数为偶数。(显然,偶数+偶数=偶数)
  2. 总边数为偶数。(显然,若有奇数条边他造成的入度/出度的总数量都为奇数,但偶数相加还是偶数)

假设我们当前已经满足了以上两点,考虑如何构造方案。

(不可能有奇数个点的度数为奇数,这样总度数就为奇数了)

考虑利用这两条要求构造方案,我们不妨对图跑一个生成树,对于树边我们先不给他定向,对于非树边随意定向。

我们从生成树的叶子节点往上考虑,每次给通往父亲的边定向即可。

设我们当前考虑到了点u,此时和他有关的边只差和父亲的没有定向。

由于u的总度数为偶数,则他此时不考虑父亲边的情况下,入度和出度必定有一个为奇数,我们用树边补上即可。

那么这样子操作过后,根节点的度数能否保证呢?

显然可以,因为总的入度/出度都为偶数,然后其他节点的入度/出度都为偶数,所以根节点也满足条件。

#include<bits/stdc++.h>
#define p_b push_back
#define m_p make_pair
#define u first
#define v second
#define int long long
#define pii pair<int,int>
using namespace std;
inline int rd(){
int x=0,f=1; char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if (ch=='-') f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
return x*f;
}
const int N=1e5+5,INF=0x3f3f3f3f3f3f3f3f;
vector<pii> G,E[N];
vector<int> vec;
int n,m;
int fa[N],du[N],in[N],out[N];
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void dfs(int x,int dad,int id){
for(auto i : E[x]){
if(i.first==dad) continue;
dfs(i.first,x,i.second);
}
if(x==1) return;
if((in[x]&1))G[id]=m_p(dad,x),in[x]++,out[dad]++;
else G[id]=m_p(x,dad),in[dad]++,out[x]++;
}
signed main(){
n=rd();m=rd();
pii tmp;
for(int i=1;i<=m;i++){
tmp.u=rd(),tmp.v=rd();
du[tmp.u]++,du[tmp.v]++;
G.p_b(tmp);
}
for(int i=1;i<=n;i++)if((du[i]&1))vec.p_b(i);
for(int i=0,j=1;j<(int)vec.size();i+=2,j+=2){
G.p_b(m_p(vec[i],vec[j]));
m++;
}
if(m&1) G.p_b(m_p(1,1)),m++;
for(int i=1;i<=n;i++) fa[i]=i;
int cnt=0;
for(auto i : G){
int fu=find(i.u),fv=find(i.v);
if(fu==fv){
out[i.u]++;
in[i.v]++;
}
else{
fa[fu]=fv;
E[i.u].p_b(m_p(i.v,cnt));
E[i.v].p_b(m_p(i.u,cnt));
}
cnt++;
}
dfs(1,0,-1);
printf("%lld\n",m);
for(auto i : G)printf("%lld %lld\n",i.u,i.v);
return 0;
}
posted @   123456xwd  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示