AGC032C Three Circuits
做法
分讨题。
边的回路问题,自然想到欧拉回路,于是在欧拉回路上考虑。这就要求原图存在欧拉回路,因此如果有奇度点就直接输出 No。
若存在 \(u\) 使得 \(deg_u\ge 6\),则显然可以划分。
接下来对 \(4\) 度点数量分讨,记 \(4\) 度点数量为 \(cnt\)。
若 \(cnt=0\),则原图为简单环,不合法。
若 \(cnt=1\),则原图为 \(8\) 字型,不合法。
若 \(cnt=2\),设这两个点为 \(\text{a,b}\),则欧拉回路有两种可能:
- \(\dots\text{a}\dots\text{b}\dots\text{a}\dots\text{b}\dots\),画一下图,可以发现无法构造。
- \(\dots\text{a}\dots\text{a}\dots\text{b}\dots\text{b}\dots\) 或 \(\dots\text{a}\dots\text{b}\dots\text{b}\dots\text{a}\dots\)(欧拉回路是环,所以这两种本质相同),画一下图,设欧拉回路为 \(\text{AaBaCbDbE}\),则构造为 \(\text{AaCbE},\text{aBa},\text{bDb}\)。
对于一个图,容易证明不存在两个欧拉回路同时满足这两种情况(画图即可)。
若 \(cnt\ge 3\),取出任意 \(3\) 个 \(4\) 度点 \(\text{a,b,c}\),继续分讨欧拉回路:
- 连续经过同一个 \(4\) 度点,即形如 \(\dots\text{aAa}\dots\),则先取出 \(\text{aAa}\) 这个回路,剩下的部分一定可以分成至少 \(2\) 个回路。
- \(\dots\text{a}\dots\text{b}\dots\text{c}\dots\text{a}\dots\text{b}\dots\text{c}\dots\),画图容易得到构造。
- \(\dots\text{a}\dots\text{b}\dots\text{c}\dots\text{a}\dots\text{c}\dots\text{b}\dots\),容易得到构造。
- \(\dots\text{a}\dots\text{b}\dots\text{c}\dots\text{b}\dots\text{a}\dots\text{c}\dots\),容易得到构造。
因此若 \(cnt\ge 3\),一定合法。
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
typedef pair<ll,ll> pll;
template<typename T>
void chkmin(T &x,const T &y){x=min(x,y);}
template<typename T>
void chkmax(T &x,const T &y){x=max(x,y);}
const int inf=0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f3f;
const int N=100005;
int n,m,vis[N<<1],cur[N];
struct Edge{
int u,v;
};
vector<Edge> es;
vector<int> G[N];
void addEdge(int u,int v){
G[u].push_back(es.size());
es.push_back({u,v});
G[v].push_back(es.size());
es.push_back({v,u});
}
vector<int> euler;
void dfs(int u){
for(int &i=cur[u];i<G[u].size();i++){
int e=G[u][i];
if(vis[e]) continue;
vis[e]=vis[e^1]=1;
dfs(es[e].v);
}
euler.push_back(u);
}
void no(){
printf("No\n");
exit(0);
}
void yes(){
printf("Yes\n");
exit(0);
}
int main(){
scanf("%d%d",&n,&m);
if(n==1) no();
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v);
}
for(int i=1;i<=n;i++) if(G[i].size()&1) no();
int cnt=0;
for(int i=1;i<=n;i++){
if(G[i].size()>=6) yes();
if(G[i].size()==4) cnt++;
}
if(cnt<=1) no();
if(cnt>=3) yes();
dfs(1);
int lst=0;
cnt=0;
for(auto u:euler){
if(G[u].size()!=4) continue;
if(lst) cnt+=(lst==u);
lst=u;
}
if(!cnt) no();
else yes();
return 0;
}

浙公网安备 33010602011771号