#欧拉回路#AT4518 [AGC032C] Three Circuits
题目
给定一个 \(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");
}

浙公网安备 33010602011771号