poj 2513

http://poj.org/problem?id=2513

 

73348K        1438MS        C++        1614B
解题思路:欧拉路的应用 要点 :1、判断连通性  2、欧拉路的判断(所有的节点的度为偶数或者只有两个奇数节点)

连通性的判断: 并查集-----由于本题的节点是字符串,,并不好处理,所以用Trie树来获得id。。然后 find 、unin 和普通并查集一样,。
连通性判断:并查集的祖先节点 ,,只有一个,若有多个即 不是连通图,也就不是欧拉路。。

 

 1 #include <iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define maxn 500005
 5 using namespace std;
 6 
 7 int f[maxn];
 8 int degree[maxn];
 9 int num;
10 struct node{
11     int id;
12     struct node *next[27];
13     node(){
14         id =0;
15         memset(next,0,sizeof(next));
16     }
17 };
18 node *root = NULL;
19 
20 int  maketrie(char *s){//用trie树获得id,,,其实就是给每个节点一个编号。。。用一般的方法不好解决,,就只能用trie树了
21     node *p = root;
22     node *temp = NULL;
23     for(int i=0;i<strlen(s);i++){
24         if(p->next[s[i]-'a']==NULL){
25             temp = new node;
26             p->next[s[i]-'a']=temp;
27         }
28         p = p->next[s[i]-'a'];
29     }
30     if(p->id==0)
31         p->id = ++num;
32     return p->id;
33 }
34 
35 int find(int x){
36     if(x!=f[x])
37         f[x] = find(f[x]);
38     return f[x];
39 }
40 
41 void unin(int x, int y){
42     int fx = find (x);
43     int fy = find(y);
44     if(fx==fy)
45         return ;
46     else{
47         f[fy] = fx;
48     }
49 }
50 int main()
51 {
52     for(int i=1;i<maxn;i++)//注意此处。。。已经好几次。。i<=maxn了。。。。。runtime error。。。悲催啊。。
53         f[i] = i;
54     char s1[30],s2[30];
55     int id1,id2;
56     root = new node;
57     num =0;
58     while(scanf("%s%s",s1,s2)==2){
59         id1 = maketrie(s1);
60         id2 = maketrie(s2);
61         degree[id1]++;//记录其节点的度数
62         degree[id2]++;
63         unin(id1,id2);
64     }
65     int s = find(1);
66     int cnt =0;
67     for(int i=1;i<=num;i++){
68         if(degree[i]%2==1)
69             cnt++;
70         if(cnt>2){
71             printf("Impossible\n");
72             return 0;
73         }
74         if(find(i)!=s){//仅只有一个祖先节点,要不然就不是连通图。。就更不是欧拉路了。。
75             printf("Impossible\n");
76             return 0;
77         }
78     }
79     if(cnt==1){//cnt 有可能为1.。。所以特殊说明。。
80          printf("Impossible\n");
81     }
82     else{
83         printf("Possible\n");
84     }
85 
86     return 0;
87 }

 

转载于:https://www.cnblogs.com/Bang-cansee/p/3240699.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值