题解 CF9E Interesting Graph and Apples

这道题,用并查集

题意+Idea

大致就是给你(n)个点,这(n)个点之间有(m)条边相连,问能不能再添加几条边,使这(n)个点刚好能围成一个圈.

因为是无向图,判断能否成一个圈,也就是一个(father),所以用了并查集。

Code

#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
1
1 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
0"),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
",ans);
		for(int i=0;i<ans;i++) printf("%d %d
",e[i].u,e[i].v);
	}
	else return puts("NO"),0;
    return 0;
}

bu yao chao xi

不随波,追随梦;不逐流,攀耸峰。不卑,补我所失;不亢,胜我所向。
原文地址:https://www.cnblogs.com/cbyyc/p/11444994.html