Trees |
Time Limit: 2500ms, Special Time Limit:6000ms, Memory Limit:32768KB |
Problem 11348 : No special judgement |
Problem description |
A graph consists of a set of vertices and edges between pairs of vertices. Two vertices are connected if there is a path (subset of edges) leading from one vertex to another, and a connected component is a maximal subset of vertices that are all connected to each other. A graph consists of one or more connected components. A tree is a connected component without cycles, but it can also be characterized in other ways. For example, a tree consisting of n vertices has exactly n-1 edges. Also, there is a unique path connecting any pair of vertices in a tree. Given a graph, report the number of connected components that are also trees. |
Input |
The input consists of a number of cases. Each case starts with two non-negative integers n and m, satisfying n ≤ 500 and m ≤ n(n-1)/2. This is followed by m lines, each containing two integers specifying the two distinct vertices connected by an edge. No edge will be specified twice (or given again in a different order). The vertices are labelled 1 to n. The end of input is indicated by a line containing n = m = 0. |
Output |
For each case, print one of the following lines depending on how many different connected components are trees (T > 1 below): Case x: A forest of T trees. Case x: There is one tree. Case x: No trees. x is the case number (starting from 1). |
Sample Input |
6 3 1 2 2 3 3 4 6 5 1 2 2 3 3 4 4 5 5 6 6 6 1 2 2 3 1 3 4 5 5 6 6 4 0 0 |
Sample Output |
Case 1: A forest of 3 trees. Case 2: There is one tree. Case 3: No trees. |
Problem Source |
2012 Rocky Mountain Regional Contest |
题意: 给定图中,树的颗数。
图中可能有环,并查集,记录构成环的任意一点,最后利用此点处理环,可能有很高效的处理方法,但是这个数据规模这么做够了。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
#include <vector>
#include <stack>
#define Max(a,b) ((a)>(b)?(a):(b))
using namespace std;
typedef long long LL ;
const int size=508 ;
int k=1 ;
struct Me{
int N ;
int M ;
int father[size] ;
vector<int>cycle ;
Me(){} ;
Me(int n,int m):N(n),M(m){
for(int i=1;i<=N;i++)
father[i]=i ;
cycle.clear() ;
}
int find_father(int x){
if(father[x]==x)
return x ;
else
return father[x]=find_father(father[x]) ;
}
void Union(){
int x ,y ,f=1;
for(int i=1;i<=M;i++){
scanf("%d%d",&x,&y) ;
int f_x=find_father(x) ;
int f_y=find_father(y) ;
if(f_x==f_y)
cycle.push_back(x) ;
else
father[f_x]=f_y ;
}
printf("Case %d: ",k++) ;
}
void gao(){
this->Union() ;
set<int>st ;
set<int>cycle_father ;
st.clear() ;
cycle_father.clear() ;
for(int i=0;i<cycle.size();i++)
cycle_father.insert(find_father(cycle[i])) ;
for(int i=1;i<=N;i++){
int f=find_father(i) ;
if(cycle_father.find(f)!=cycle_father.end())
continue ;
else
st.insert(f) ;
}
if(st.size()==0)
puts("No trees.") ;
else if(st.size()==1)
printf("There is one tree.\n") ;
else
printf("A forest of %d trees.\n",st.size()) ;
}
};
int main(){
int n , m ;
while(scanf("%d%d",&n,&m)){
if(n==0&&m==0)
break ;
Me me(n,m) ;
me.gao() ;
}
return 0 ;
}