#歐拉回路#AT4518 [AGC032C] Three Circuits
阿新 • • 發佈:2021-11-13
歐拉回路
題目
給定一個 \(n\) 個點,\(m\) 條邊的簡單無向連通圖,
問是否能將邊分成三部分,使每部分都能成為環
分析
每個點的度數都得為偶數,這不由得想到了歐拉回路。
如果整張圖是一個簡單環那麼一定無解。
如果存在一個點的度數大於等於 6,也就是通過這個點可以產生至少 3 個環。
那麼剩下討論點的度數為 4 的情況,如果只有一個度數為 4 的點顯然無解。
如果個數超過 2,那麼一定可以拆成 3 個環。
剩下就是個數正好為 2 的情況,如果度數為 4 的兩個點本身有兩個環就可以拆成 3 個環。
否則只剩下這兩個點連線四條鏈的情況,一定無解。
可以先割掉兩個度數為 4 的點判斷每個點是否能只與其中一點連通
程式碼
#include <cstdio> #include <cctype> using namespace std; const int N=100011; struct node{int y,next;}e[N<<1]; int v[N],as[N],n,m,deg[N],four,fi,se,et=1; int iut(){ int ans=0; char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=ans*10+c-48,c=getchar(); return ans; } void dfs(int x){ v[x]=1; for (int i=as[x];i;i=e[i].next) if (v[e[i].y]==-1) se=fi,fi=e[i].y; else if (!v[e[i].y]) dfs(e[i].y); } int main(){ n=iut(),m=iut(); for (int i=1;i<=m;++i){ int x=iut(),y=iut(); e[++et]=(node){y,as[x]},as[x]=et,++deg[x]; e[++et]=(node){x,as[y]},as[y]=et,++deg[y]; } for (int i=1;i<=n;++i) if (deg[i]&1) return !puts("No"); for (int i=1;i<=n;++i) if (deg[i]>=6) return !puts("Yes"); for (int i=1;i<=n;++i) if (deg[i]>=4) se=fi,fi=i,++four; if (four!=2) return !puts(four<2?"No":"Yes"); v[fi]=v[se]=-1; for (int i=1;i<=n;++i) if (!v[i]){ fi=se=0,dfs(i); if (fi==se) return !puts("Yes"); } return !puts("No"); }