题意:给定一些结点之间的有向边(父子关系),问是否是一棵树
题解:1.首先判定是否是空树,这个地方是个坑,容易漏判。2.判定树的根节点数量。3.从根节点开始搜索(我用的DFS),对找到的点打访问标记,如果出现重复访问就不是树。4.枚举结点,如果有没有被访问到的的结点说明不是树
数据范围没给,但是亲测n不大于10000
1 #include<iostream>
2 #include<algorithm>
3 #include<vector>
4 #include<cstdio>
5 using namespace std;
6 struct pointtype
7 {
8 bool vis;
9 bool in;
10 vector<int> next;
11 bool dfs_vis;
12 }point[10001];
13 int test=0;
14 bool flag;
15 void dfs(int x)
16 {
17 point[x].dfs_vis=true;
18 vector<int>::iterator it;
19 for(it=point[x].next.begin();it!=point[x].next.end()&&flag;it++)
20 {
21 if(point[*it].dfs_vis)
22 {
23 flag=false;
24 return ;
25 }
26 if(flag)
27 {
28 dfs(*it);
29 }
30 }
31 return;
32 }
33 int main()
34 {
35 int n=10000;
36 while(true)
37 {
38 for(int i=1;i<=n;i++)
39 {
40 point[i].vis=false;
41 point[i].in=false;
42 point[i].next.clear();
43 point[i].dfs_vis=false;
44 }
45 flag=true;
46 int x;
47 int y;
48 scanf("%d%d",&x,&y);
49 if(x==-1&&y==-1)
50 {
51 break;
52 }
53 if(x==0&&y==0)
54 {
55 printf("Case %d is a tree.\n",++test);
56 continue;
57 }
58 point[x].next.push_back(y);
59 point[y].in=true;
60 point[x].vis=true;
61 point[y].vis=true;
62 while(true)
63 {
64 scanf("%d%d",&x,&y);
65 if(x==0&&y==0)
66 {
67 break;
68 }
69 point[x].next.push_back(y);
70 point[y].in=true;
71 point[x].vis=true;
72 point[y].vis=true;
73 }
74 int res=0;
75 int tip=0;
76 for(int i=1;i<=n;i++)
77 {
78 if(point[i].vis)
79 {
80 if(point[i].in==false)
81 {
82 res+=1;
83 tip=i;
84 }
85 }
86 }
87 if(res!=1)
88 {
89 printf("Case %d is not a tree.\n",++test);
90 continue;
91 }
92 dfs(tip);
93 if(!flag)
94 {
95 printf("Case %d is not a tree.\n",++test);
96 continue;
97 }
98 for(int i=1;i<=n;i++)
99 {
100 if(point[i].vis&&!point[i].dfs_vis)
101 {
102 flag=false;
103 break;
104 }
105 }
106 if(flag)
107 {
108 printf("Case %d is a tree.\n",++test);
109 continue;
110 }
111 else
112 {
113 printf("Case %d is not a tree.\n",++test);
114 continue;
115 }
116 }
117 return 0;
118 }