题意:求一个无向图的连通度和环数。
思路:先用并查集求出图的连通度。对于一个环,每个点的度数都是2,有不满足的点就记录该根节点,最后删去。
//#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<string>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
typedef unsigned long long llu;
typedef long long ll;
const double PI=acos(-1.0);
const double eps=1e-10;
#define inf 0x3f3f3f3f
#define isLeapYear(x) x%100!=0 && x%4==0 || x%400==0 ? 1 : 0
#define yearLen 5005
#define Riep(n) for(int i=1;i<=n;i++)
#define Riop(n) for(int i=0;i<n;i++)
#define Rjep(n) for(int j=1;i<=n;i++)
#define Rjop(n) for(int j=0;j<n;j++)
#define mst(ss,a) memset(ss,a,sizeof ss)
#define N 100005
#define mod 9901
#define CLR(x) memset(x,0,sizeof x)
#define Lowbit(x) (x&(-x))
#define Find(x,y) (Sum(x,y)-Sum(x-1,y)-Sum(x,y-1)+Sum(x-1,y-1))
int par[N],hit[N],se[N];
//父亲、高度、点的度数
bool flag[N];
//初始化
void init(int n){
Riep(n){
par[i]=i;
hit[i]=0;
se[i]=0;
flag[i]=0;
}
}
//查询树根
int fin(int x){
if(x==par[x]){
return x;
}
else
return par[x]=fin(par[x]);
}
//合并x和y的集合
void unite(int x,int y){
x=fin(x);
y=fin(y);
if(x==y){
return;
}
if(hit[x]<hit[y]){
par[x]=y;
}
else{
par[y]=x;
if(hit[x]==hit[y]){
hit[x]++;
}
}
}
int main(){
int n,m,a,b;
while(~scanf("%d%d",&n,&m),n||m){
init(n);
Riep(m){
scanf("%d%d",&a,&b);
unite(a+1,b+1);
se[a+1]++;
se[b+1]++;
}
int ans1=0,ans2=0;
Riep(n){
int tmp=fin(i);
if(tmp==i){
ans1++;
ans2++;
}
//环的每个节点度数都是2,不符合则记录根节点
if(se[i]!=2){
flag[tmp]=1;
}
}
Riep(n){
//去掉不合题意根节点
if(flag[i]){
ans2--;
}
}
printf("%d %d\n",ans1,ans2);
}
return 0;
}