首页 > 代码库 > POJ 1300 Door Man

POJ 1300 Door Man

判断是否欧拉回路。

很蛋疼的一道题,加上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");
    }
}