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. ") ; else printf("A forest of %d trees. ",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 ; }