hdu 4096 判断路径
思路:将每个关系当成一条有向边,查询时就判断之间存在路径。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<map> #define Maxn 210 using namespace std; map<string,int> g; map<string,int> ver; int head[Maxn*2],vi[Maxn*2],e; struct Edge{ int u,v,next; }edge[Maxn*Maxn*2]; void add(int u,int v){ edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++; } bool dfs(int u,int x) { int i,v; vi[u]=1; if(u==x) return true; for(i=head[u];i!=-1;i=edge[i].next){ v=edge[i].v; if(vi[v]) continue; if(dfs(v,x)) return true; } return false; } int main() { char str[101001],s1[Maxn],s2[Maxn],s3[Maxn],s4[Maxn],s5[Maxn],s6[Maxn]; int cnt,num,i,j,t,Ca=0,u,v; scanf("%d",&t); getchar(); while(t--){ cnt=0; memset(vi,0,sizeof(vi)); memset(head,-1,sizeof(head)); e=0; g.clear(); ver.clear(); printf("Case #%d:\n",++Ca); while(cin.getline(str,2000,'\n')){ int l=strlen(str); if(str[l-1]=='!'){ printf("\n"); break; } num=sscanf(str,"%s %s %s %s %s %s",s1,s2,s3,s4,s5,s6); if(num==3){ l=strlen(s3); if(s3[l-1]=='.'){ s3[l-1]='\0'; if(s2[0]=='a'){ if(!g[s1]) g[s1]=++cnt; if(!g[s3]) g[s3]=++cnt; u=g[s1]; v=g[s3]; }else{ if(!g[s1]) g[s1]=++cnt; if(!ver[s3]) ver[s3]=++cnt; u=g[s1]; v=ver[s3]; } add(u,v); } else{ s3[l-1]='\0'; if(!g[s2]) g[s2]=++cnt; u=g[s2]; if(s1[0]=='a'){ if(!g[s3]) g[s3]=++cnt; v=g[s3]; } else{ if(!ver[s3]) ver[s3]=++cnt; v=ver[s3]; } memset(vi,0,sizeof(vi)); if(dfs(u,v)){ printf("Y"); }else { printf("M"); } } } else{ l=strlen(s6); if(s6[l-1]=='.'){ s6[l-1]='\0'; if(s5[0]=='a'){ if(!ver[s4]) ver[s4]=++cnt; if(!g[s6]) g[s6]=++cnt; u=ver[s4]; v=g[s6]; }else{ if(!ver[s4]) ver[s4]=++cnt; if(!ver[s6]) ver[s6]=++cnt; u=ver[s4]; v=ver[s6]; } add(u,v); } else{ s6[l-1]='\0'; if(s1[0]=='c'){ if(!ver[s5]) ver[s5]=++cnt; if(!ver[s6]) ver[s6]=++cnt; u=ver[s5]; v=ver[s6]; } else { if(!ver[s5]) ver[s5]=++cnt; if(!g[s6]) g[s6]=++cnt; u=ver[s5]; v=g[s6]; } memset(vi,0,sizeof(vi)); if(dfs(u,v)){ printf("Y"); }else { printf("M"); } } } } } return 0; }