题意:给你一堆边,有向边,然后这个图是否构成一颗树。
他这里树的定义是这样的:只有一个入度为0的点,是根节点。
每一个节点(除根节点)都只有一条边指向他,也就是入度等于1。
从根节点到任意一个节点的路径是唯一的。
满足上面三个要求的话就是树。
OK。那就可以搞了,A了之后看DISCUSS里面都说是并查集搞的,我是直接爆搜的。
思路:首先找出入度为0的点,如果有多个,那么不是树。
然后找度数大于1的,如果有,那么不是树。
最后从根节点爆搜一遍,看节点是否都只访问到一次。
注意0 0 的时候代表空树,他也是一颗树,我想这是这道题唯一的trick了。
#include <set> #include <map> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <string> #include <vector> #include <iomanip> #include <cstring> #include <iostream> #include <algorithm> #define Max 2505 #define FI first #define SE second #define ll long long #define PI acos(-1.0) #define inf 0x3fffffff #define LL(x) ( x << 1 ) #define bug puts("here") #define PII pair<int,int> #define RR(x) ( x << 1 | 1 ) #define mp(a,b) make_pair(a,b) #define mem(a,b) memset(a,b,sizeof(a)) #define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) using namespace std; #define N 111111 struct KK{ int e , next ; }ed[N] ; int head[N] , num ; void init(){ mem(head , -1) ;num = 0 ; } void add(int s , int e ){ ed[num].e = e ;ed[num].next = head[s] ; head[s] = num ++ ; } int in[N] , out[N] ; int vis[N] ; int iscr = 0 ; void dfs(int now){ vis[now] ++ ; iscr ++ ;if(iscr >= 1000000)return ;//怕SB数据死循环。 for (int i = head[now] ; ~i ; i = ed[i].next ){ int e = ed[i].e ; dfs(e) ; } } int main() { int a , b ; int mx = 0 , ca = 0 ; while(cin >> a >> b ){ mx = 0 ; if(a == -1 && b == -1)break ; printf("Case %d ", ++ ca) ; if(!a && !b){ puts("is a tree.") ;continue ; } init() ; mem(in , 0) ; mem(out ,0) ;mem(vis ,0) ; mx = max(max(a , b) , mx) ; out[a] ++ , in[b] ++ ; add(a , b) ; vis[a] = vis[b] = 1 ; while(cin >> a >> b , (a + b)){ add(a , b) ; vis[a] = vis[b] = 1 ; mx = max(mx , max(a , b)) ; out[a] ++ , in[b] ++ ; } int root = -1 ;int rootnum = 0 ;bool isok = false ; for (int i = 1 ; i <= mx ; i ++ )if(vis[i] && in[i] == 0)root = i , rootnum ++ ;//根节点和根节点个数 for (int i = 1 ; i <= mx ; i ++ )if(in[i] >= 2)isok = true ;//每个节点的度数 if(root == -1 || rootnum >= 2 || isok)puts("is not a tree.") ; else{ mem(vis ,0) ; dfs(root) ; iscr = false ; bool flag = false ; for (int i = 1 ; i <= mx ; i ++ )if(vis[i] >= 2)flag = true ;//访问到2次或者以上 if(flag)puts("is not a tree.") ; else puts("is a tree.") ; } } return 0 ; }