题解CF9E興味深いグラフとりんご

でこの質問、互いに素セットああ

質問の意味\(+アイデア\)

あなたは、実質的に提供することです\(\ N-)のポイントを、どの\(\ N-)ポイント間を持っている\(m個\)エッジが接続され、Qは、いくつかの側面を追加することができますように\(\ N-)のポイント円を形成するだけで十分。

それは無向グラフであるので、それは円かどうか、すなわちA判定する\(父\) 互いに素なセットを持つので。

\(コード\)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<string>
#define ll long long
#define maxn 105
#define inf 2147483647
#define mod 10003
#define eps 1e-6
#define pi acos(-1.0)
#define de(x) ((x)*(x))
using namespace std; 
inline int read(){
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int deep[maxn],fa[maxn];//deep[]记录度数 
int n,m,ans;
struct Node{//记录加边情况 
    int u,v;
}e[1100];
inline void init(){for(int i=1;i<=n;i++) fa[i]=i;}
inline int find(int x){
    if(x==fa[x]) return x;
    return fa[x]=find(fa[x]);
}
inline void Union(int x,int y){
    int xx=find(x),yy=find(y);
    if(xx!=yy) fa[xx]=yy;
}
inline bool check(){
    for(int i=1;i<=n;i++)
    if(deep[i]<2){
        for(int j=i+1;j<=n;j++)
        if(deep[j]<2&&find(i)!=find(j)){
            Union(i,j);
            e[ans].u=i; e[ans].v=j;
            ans++;
            deep[i]++; deep[j]++;
            break;
        }
        if(deep[i]<2)
        for(int j=i+1;j<=n;j++)
        if(deep[j]<2&&find(i)!=find(j)){
            Union(i,j);
            e[ans].u=i; e[ans].v=j;
            ans++;
            deep[i]++; deep[j]++;
            break;
        }
    }
    int cot=0;
    for(int i=1;i<=n;i++){
        if(deep[i]!=1&&deep[i]!=2) return false;
        if(deep[i]==1) cot++;
    }
    if(cot==2) return true;
    else return false;
}
bool flag,sign;
signed main(){
    n=read(); m=read();
    if(n==1&&m==0) return printf("YES\n1\n1 1"),0;//特判,只有一个点和0条边; 
    int tmp=0; flag=sign=false;
    init(); ans=0;
    for(int i=1;i<=m;i++){
        int x=read(),y=read();
        deep[x]++; deep[y]++;
        if(find(x)==find(y)) flag=true;//如果为环,标记为一 
        Union(x,y);
    }
    for(int i=1;i<=n;i++) tmp=max(tmp,deep[i]);
    if(tmp>2) return puts("NO"),0;//如果度数>2 ,肯定为0; 
    if(flag){/若原图有环 
        int t=find(1);
        for(int i=2;i<=n;i++)
        if(t==find(i)&&deep[i]==2) continue;
        else{sign=true; break;}
        if(!sign) return printf("YES\n0"),0;
        else return puts("NO");
    }
    if(check()){
        int p[2],cnt=0;
        for(int i=1;i<=n;i++) if(deep[i]==1) p[cnt++]=i;
        e[ans].u=p[0]; e[ans++].v=p[1];
        puts("YES"); printf("%d\n",ans);
        for(int i=0;i<ans;i++) printf("%d %d\n",e[i].u,e[i].v);
    }
    else return puts("NO"),0;
    return 0;
}

\(\ Soutは{BU〜八尾〜チャオ〜第XI} \)

おすすめ

転載: www.cnblogs.com/cbyyc/p/11444994.html