CF527E Data Center Drama(構造+歐拉回路)
阿新 • • 發佈:2018-12-14
大意:
給你一個無向圖。
要求加最少的邊,然後給這些無向圖的邊定向,使得每一個點的出入度都是偶數。
輸出定向後的邊數和邊集。
n<=10^5 m<=2*10^5
很巧妙的構造題……
可以發現答案的下界是\(度數為奇數的點個數m + 度數為奇數的點個數/2\)
因為是無向圖,度數為奇數的點不可能有奇數個,於是考慮往每兩個度數為奇數的點間連一條邊。於是就可以愉快地跑歐拉回路啦。跑出來後在歐拉回路上構造像\(a\rightarrow b\leftarrow c\rightarrow d ……y\rightarrow x\leftarrow a\)
那如果構造出來的歐拉回路是類似於\(a- b- c- a\)這樣,只有奇數條邊,怎麼分都分不好怎麼辦?起點和終點加個自環就OK了。
程式碼:
#include <bits/stdc++.h> #define N 100005 using namespace std; void rd(int &x){ int y=0;char c=getchar(); while(c<'0' || c>'9') c=getchar(); while(c>='0' && c<='9') y=y*10+c-'0',c=getchar(); x=y; } struct ed{ int v,nxt; bool f; }e[N<<3]; int head[N],cnt=1,deg[N],p[1000005],tot=0; bool vis[N]; void add(int u,int v){ e[++cnt]=(ed){v,head[u],0},head[u]=cnt; e[++cnt]=(ed){u,head[v],0},head[v]=cnt; } void dfs(int u){ for(int &i=head[u];i;i=e[i].nxt){ int to=e[i].v; if(!e[i].f){ e[i].f=1; e[i^1].f=1; dfs(to); } } p[++tot]=u; } int main(){ int n,m,a,b,ans=0,lst=0,qwq=0,i; rd(n),rd(m); for(i=1;i<=m;++i){ rd(a),rd(b); add(a,b); deg[a]++,deg[b]++; } for(i=1;i<=n;++i){ if(deg[i]&1){ ans++; if(ans%2==1) lst=i; else if(lst) add(lst,i); } } m+=ans/2; if(m&1) add(1,1),m++; printf("%d\n",m); for(i=1;i<=n;++i){ if(!vis[i]){ tot=qwq=0; dfs(i); for(i=1;i<tot;++i) printf("%d %d\n",p[i+qwq],p[i+(!qwq)]),qwq^=1; } } }