判断是否欧拉回路。
很蛋疼的一道题,加上DFS判所有点是否连通就无限WA。(并查集也可判)
直接定理就AC了。都不知道所有点是不是在一个 连通块里面。
然后他们说:Your master is a particularly absent-minded lout and continually leaves doors open throughout a particular floor of the house.
这句话就表明了连通……问题是,中间关几个门让他无法通过,前后都有门没关怎么办……
比如:
START 0 5
1 1
4 4
END
这怎么关门…… POJ AC的程序完全过不了这组数据啊。
好吧,贴上POJ AC程序,再贴上→_→ 真正意义上正确的程序。
AC 代码:
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<queue> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x7fffffff #define eps 1e-6 using namespace std; int n,m; int in[21],out[21]; int door; bool Euler() { int s[21],cot=0; for(int i=0; i<n; i++) { if(in[i]&1)s[cot++]=i; if(out[i]!=in[i])return 0; } if(cot>2||cot==1)return 0; if(cot==0&&m==0)return 1; if(s[0]==0&&s[1]==m||s[0]==m&&s[1]==0)return 1; return 0; } int main() { char str[100]; while(scanf("%s",str)!=EOF) { if(strcmp(str,"ENDOFINPUT")==0)return 0; scanf("%d%d",&m,&n); gets(str); door=0; memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); for(int i=0; i<n; i++) { gets(str); int c=0; for(int j=0; j<=strlen(str); j++) { if(str[j]>='0'&&str[j]<='9') c=c*10+str[j]-'0'; else { if(c==0)continue; door++; in[c]++,out[i]++; out[c]++,in[i]++; c=0; } } } while(gets(str),strcmp(str,"END")); bool flag=1; flag=Euler(); if(flag)printf("YES %d\n",door); else puts("NO"); } }
“错误”代码:
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<queue> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x7fffffff #define eps 1e-6 using namespace std; int g[21][21]; int n,m; int in[21],out[21]; int ans; bool vis[21]; bool Euler() { for(int i=0; i<n; i++) { //printf("%d :%d %d\n",i,in[i],out[i]); if(out[i]!=in[i])return 0; } return 1; } void dfs(int i) { int j; for(j=0; j<n; j++) { if(g[i][j]==0)continue; break; } if(j==n)return; g[i][j]--,g[j][i]--; vis[i]=vis[j]=1; ans++; //printf("%d->%d\n",i,j); dfs(j); } int main() { char str[100]; while(scanf("%s",str)!=EOF) { if(strcmp(str,"ENDOFINPUT")==0)return 0; scanf("%d%d",&m,&n); gets(str); memset(g,0,sizeof(g)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); for(int i=0; i<n; i++) { gets(str); int c=0; for(int j=0; j<=strlen(str); j++) { if(str[j]>='0'&&str[j]<='9') c=c*10+str[j]-'0'; else { if(c==0)continue; g[i][c]++,in[c]++,out[i]++; g[c][i]++,out[c]++,in[i]++; c=0; } } } while(gets(str),strcmp(str,"END")); bool flag=1; flag=Euler(); memset(vis,0,sizeof(vis)); ans=0; dfs(m); for(int i=0; i<n; i++) if(!vis[i])flag=0; if(flag)printf("YES %d\n",ans); else puts("NO"); } }
POJ 1300 Door Man,布布扣,bubuko.com
原文:http://blog.csdn.net/dongshimou/article/details/37390253