码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1181 并查集 or SPFA

时间:2014-07-09 21:02:46      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   java   color   strong   

变形课

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 12773    Accepted Submission(s): 4733


Problem Description
呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规律:如果咒语是以a开头b结尾的一个单词,那么它的作用就恰好是使A物体变成B物体. 
Harry已经将他所会的所有咒语都列成了一个表,他想让你帮忙计算一下他是否能完成老师的作业,将一个B(ball)变成一个M(Mouse),你知道,如果他自己不能完成的话,他就只好向Hermione请教,并且被迫听一大堆好好学习的道理.
 
Input
测试数据有多组。每组有多行,每行一个单词,仅包括小写字母,是Harry所会的所有咒语.数字0表示一组输入结束.
 
Output
如果Harry可以完成他的作业,就输出"Yes.",否则就输出"No."(不要忽略了句号)
 
Sample Input
so
soon
river
goes
them
got
moon
begin
big
0
 
Sample Output
Yes.
 
Hint
Hint
Harry 可以念这个咒语:"big-got-them".
 
 
就像成语接龙一样,每个单词的首字符和前面单词的尾字符相等,只要使得首单词的首字符为‘b’且尾单词的尾字符为‘m‘就输出yes.   若不能构成这个结构输出no.
 
那么就有两种方法,SPFA或者并查集。
 
SPFA算法使dis[‘m‘-‘a‘]!=inf即从‘m‘-‘a‘到‘b‘-‘a‘之间有一条路径则满足条件输出yes。
 
SPFA代码:
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <vector>
 5 #include <queue>
 6 #define inf 999999999
 7 using namespace std;
 8 
 9 
10 int map[27][27];
11 int dis[27];
12 int visited[27];
13 
14 
15 void init()
16 {
17     for(int i=0;i<27;i++)
18     {
19         visited[i]=0;
20         dis[i]=inf;
21         for(int j=0;j<27;j++)
22         map[i][j]=inf;
23     }
24 }
25 
26 
27 void SPFA()
28 {
29     queue<int>Q;
30     int u, v;
31     Q.push(1);
32     visited[1]=1;
33     dis[1]=0;
34     while(!Q.empty())
35     {
36         u=Q.front();
37         Q.pop();
38         visited[u]=0;
39         for(v=0;v<26;v++)
40         {
41             if(map[u][v]!=inf&&dis[v]>dis[u]+map[u][v])
42             {
43                 dis[v]=dis[u]+map[u][v];
44                 if(!visited[v])
45                 {
46                     Q.push(v);
47                     visited[v]=1;
48                 }
49             }
50         }
51     }
52 }
53 main()
54 {
55     char a[1001];
56     while(scanf("%s",a)!=EOF)
57     {
58         init();
59         int n=strlen(a);
60         map[a[0]-a][a[n-1]-a]=1;
61         while(scanf("%s",a))
62         {
63             if(strcmp(a,"0")==0) break;
64             int n=strlen(a);
65             map[a[0]-a][a[n-1]-a]=1;
66         }
67         SPFA();
68         if(dis[m-a]!=inf)
69         printf("Yes.\n");
70         else printf("No.\n");
71     }
72 }

 

 

用并查集就是始终保持‘b‘-‘a‘为根结点,其他点为儿子,若father[‘b‘-‘a‘]==findroot(‘m‘-‘a‘)则满足条件。

并查集代码:

 1 #include <iostream>  
 2 #include <string>  
 3 using namespace std;  
 4 string str;  
 5 int father[30];  
 6 int find(int x)  
 7 {  
 8     if(x!=father[x])  
 9         father[x]=find(father[x]);  
10     return father[x];  
11 }  
12 void mere(int x,int y)  
13 {  
14     x=find(x);  
15     y=find(y);  
16     if(x!=y)  
17         father[y]=x;  
18 }  
19 int main()  
20 {  
21     int i;  
22     while(cin>>str)  
23     {  
24         memset(father,0,sizeof(father));  
25         for(i=0;i<29;i++)  
26             father[i]=i;  
27         int len=str.length();  
28         int x=find(str[0]-a);  
29         int y=find(str[len-1]-a);  
30         if(x!=y&&y!=b-a)  
31             mere(x,y);  
32         while(cin>>str)  
33         {  
34             if(!str.compare("0"))  
35                 break;  
36             len=str.length();  
37             x=find(str[0]-a);  
38             y=find(str[len-1]-a);  
39             if(x!=y&&y!=b-a)  
40                 mere(x,y);  
41         }  
42         x=find(m-a);  
43         y=father[b-a];  
44         if(x!=y)  
45             cout<<"No."<<endl;  
46         else  
47             cout<<"Yes."<<endl;  
48     }  
49     return 0;  
50 }  

 

HDU 1181 并查集 or SPFA,布布扣,bubuko.com

HDU 1181 并查集 or SPFA

标签:des   style   blog   java   color   strong   

原文地址:http://www.cnblogs.com/qq1012662902/p/3829891.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!