hdu 1181 变形课,dfs /传递闭包
#include<iostream> #include<string.h> #include<stdio.h> using namespace std; const int maxn=100000; char st[maxn],et[maxn]; int vis[maxn],t; bool ok; void DFS(int x) { if(et[x]=='m') { ok=true; return; } for(int i=0; i<t; ++i) { if(vis[i]||st[i]!=et[x])continue; vis[i]=1; DFS(i); vis[i]=0; if(ok)return; } } int main() { string s; while(cin>>s) { t=0; while(s[0]!='0') { st[t]=s[0]; et[t++]=s[s.size()-1]; cin>>s; } memset(vis,0,sizeof(vis)); ok=false; for(int i=0; i<t; ++i) { if(st[i]!='b')continue; vis[i]=1; DFS(i); } if(ok)puts("Yes."); else puts("No."); } return 0; }
另一种觉得好神奇
这是一个简单的传递闭包,用floyd。不过在核心程序段里,中间顶点变量应在最外层循环,否则会出现更新不了某两顶点间是否连通。
例如:5~6可能可以更新1~6,因为可能1~5~6可以连通。但因为i已经是5了。所以i不可能变成1进而不可以更新1~6.当k在最外层的时候,正确性可以通过简单的证明来证实。
不过,这题k在中间层的循环也可以ac.一位大牛说是数据弱。同时,用字母-'a'的表示方法也很不错。这里的i和j可以互换。
View Code
#include<iostream> using namespace std; int map[28][28]; void floyd() { int i,j,k; for( k=0;k!=26;k++) for(i=0;i!=26;i++) for(j=0;j!=26;j++) map[i][j]=map[i][j]||(map[i][k]&&map[k][j]); } int main() { char a[1000]; while(scanf("%s",a)!=EOF) { if(a[0]=='0') { floyd(); if(map[1][12]) printf("Yes.\n"); else printf("No.\n"); memset(map,0,sizeof(map)); continue; } map[a[0]-'a'][a[strlen(a)-1]-'a']=1; } return 0; }
膜拜下