AGC032C Three Circuits

做法

分讨题。

边的回路问题,自然想到欧拉回路,于是在欧拉回路上考虑。这就要求原图存在欧拉回路,因此如果有奇度点就直接输出 No

若存在 \(u\) 使得 \(deg_u\ge 6\),则显然可以划分。

接下来对 \(4\) 度点数量分讨,记 \(4\) 度点数量为 \(cnt\)

\(cnt=0\),则原图为简单环,不合法。

\(cnt=1\),则原图为 \(8\) 字型,不合法。

\(cnt=2\),设这两个点为 \(\text{a,b}\),则欧拉回路有两种可能:

  1. \(\dots\text{a}\dots\text{b}\dots\text{a}\dots\text{b}\dots\),画一下图,可以发现无法构造。
  2. \(\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}\),继续分讨欧拉回路:

  1. 连续经过同一个 \(4\) 度点,即形如 \(\dots\text{aAa}\dots\),则先取出 \(\text{aAa}\) 这个回路,剩下的部分一定可以分成至少 \(2\) 个回路。
  2. \(\dots\text{a}\dots\text{b}\dots\text{c}\dots\text{a}\dots\text{b}\dots\text{c}\dots\),画图容易得到构造。
  3. \(\dots\text{a}\dots\text{b}\dots\text{c}\dots\text{a}\dots\text{c}\dots\text{b}\dots\),容易得到构造。
  4. \(\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;
}
posted @ 2025-11-13 10:05  SmpaelFx  阅读(4)  评论(0)    收藏  举报