51 Nod 1535 深海探险

                             1535 深海探险

很久很久以前的一天,一位美男子来到海边,海上狂风大作。美男子希望在海中找到美人鱼,但是很不幸他只找到了章鱼怪。

 

然而,在世界的另一端,人们正在积极的收集怪物的行为信息,以便研制出强大的武器来对付章鱼怪。由于地震的多发,以及恶劣的天气,使得我们的卫星不能很好的定位怪物,从而不能很好的命中目标。第一次射击的分析结果会反映在一张由n个点和m条边组成的无向图上。现在让我们来确定这张图是不是可以被认为是章鱼怪。

 

为了简单起见,我们假设章鱼怪的形状是这样,他有一个球形的身体,然后有很多触须连接在他的身上。可以表现为一张无向图,在图中可以被认为由三棵或者更多的树(代表触须)组成,这些树的根在图中处在一个环中(这个环代表球形身体)。

 

题目保证,在图中没有重复的边,也没有自环。

Input
单组测试数据
第一行给出两个数,n表示图中的点的个数,m表示图中边的数量。 (1≤ n≤100,0≤ m≤ n*(n-1)/2 )
接下来m行给出边的信息,
每一行有两上数x,y  (1≤ x,y≤ n,x≠y)
表示点x和点y之间有边相连。每一对点最多有一条边相连,点自身不会有边到自己。
Output
共一行,如果给定的图被认为是章鱼怪则输出"FHTAGN!"(没有引号),否则输出"NO"(没有引号)。
Input示例
6 6
6 3
6 4
5 1
2 5
1 4
5 4
Output示例
FHTAGN!

思路: 图中只有一个环 所以满足条件的图 一定是基环树
    也就是一棵树上多了一条边 所以一定有 n==m 对于 n!=m 的情况一定不成立
   当 n==m 的时候 也要DFS判断一下 图是否连通

   还有一种做法是用 并查集
    对于一条边的两个点 如果已经在 一个集合中了 那么一定存在一个环 而且这样的边一定只有一条
    最后判断一下连通性
 1 #include <cctype>
 2 #include <cstdio>
 3 #include <vector>
 4 #define min(a,b) a<b?a:b
 5 
 6 const int MAXN=110;
 7 
 8 int n,m;
 9 
10 bool dfn[MAXN];
11 
12 std::vector<int> Graph[MAXN];
13 
14 inline void read(int&x) {
15     int f=1;register char c=getchar();
16     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
17     for(;isdigit(c);x=x*10+c-48,c=getchar());
18     x=x*f;
19 }
20 
21 void DFS(int u) {
22     dfn[u]=true;
23     for(int i=0; i<Graph[u].size(); ++i) {
24         int v=Graph[u][i];
25         if(!dfn[v]) DFS(v);
26     }
27 }
28 
29 int hh() {
30     read(n);read(m);
31     
32     for(int x,y,i=1; i<=m; ++i) {
33         read(x);read(y);
34         Graph[x].push_back(y);
35         Graph[y].push_back(x);
36     }
37     
38     if(n!=m) {
39         printf("NO\n");
40         return 0;
41     }
42     
43     DFS(1);
44     
45     for(int i=1; i<=n; ++i)
46       if(!dfn[i]) {
47         printf("NO\n");
48         return 0;
49       }
50     printf("FHTAGN!\n");
51     
52     return 0;
53 }
54 
55 int sb=hh();
56 int main(int argc,char**argv) {;}
DFS
 1 #include <cctype>
 2 #include <cstdio>
 3 #include <vector>
 4 #define min(a,b) a<b?a:b
 5 
 6 const int MAXN=110;
 7 
 8 int n,m,cnt;
 9 
10 int fa[MAXN];
11 
12 std::vector<int> Graph[MAXN];
13 
14 inline void read(int&x) {
15     int f=1;register char c=getchar();
16     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
17     for(;isdigit(c);x=x*10+c-48,c=getchar());
18     x=x*f;
19 }
20 
21 int find(int x) {
22     if(x==fa[x]) return x;
23     return fa[x]=find(fa[x]);
24 }
25 
26 int hh() {
27     read(n);read(m);
28     
29     for(int i=1; i<=n; ++i) fa[i]=i;
30     for(int x,y,i=1; i<=m; ++i) {
31         read(x);read(y);
32         if(find(x)==find(y)) ++cnt;
33         else {
34             int xx=find(x);
35             int yy=find(y);
36             fa[xx]=yy;
37         }
38     }
39     
40     int root=0;
41     for(int i=1; i<=n; ++i) if(fa[i]==i) ++root;
42     if(cnt==1 && root==1) printf("FHTAGN!\n");
43     else printf("NO\n");
44     
45     return 0;
46 }
47 
48 int sb=hh();
49 int main(int argc,char**argv) {;}
并查集

 

 
posted @ 2017-10-25 20:58  拿叉插猹哈  阅读(191)  评论(0编辑  收藏  举报