Play on Words-uva 精短欧拉回路

来源:互联网 发布:linux解压tar.bz2 编辑:程序博客网 时间:2024/04/29 21:22

思路:先分析,特殊的字母,可能有的字母是当开头个数+1=当结尾个数,那么这个字母一定是开头,同理另一个特殊字母就是作为结尾的

之后其余的字母的话只可能是开头=结尾个数,如果有任何一个字母当开头的个数和结尾个数只差为2,那么回路一定不成立!

之后是构建DFS遍历

遍历的思路就是 用G[i][j]表示字母i,j是连通的!

遍历的起点我们分为2个步骤,一个是这个图是个环路

第二个是一条线性图

环路的话从哪里都可以开始遍历

线形图的话最好从开头进行遍历

一直遍历到结尾

之后看有没有没有遍历到的节点

#include<stdio.h>#include<iostream>#include<string.h>using namespace std;#define LEN 100 + 10#define MAX_SIZE  1000 + 10int G[LEN][LEN];int front[LEN];int back[LEN];int vis[LEN];int dfs(int u){    vis[u]=1;    for(int i=0;i<LEN;i++)        if(G[u][i]&&!vis[i])/*如果是连通的话*/    {        dfs(i);    }}int main(){    int N;    scanf("%d",&N);    for(int cases=1;cases<=N;cases++)    {        int n,ok=1;        scanf("%d",&n);        memset(front,0,sizeof(front));        memset(back,0,sizeof(back));        memset(G,0,sizeof(G));        memset(vis,0,sizeof(vis));        for(int i=0;i<n;i++)        {            char word[MAX_SIZE];            scanf("%s",word);            int L=strlen(word);            G[word[0]-'0'][word[L-1]-'0']++;            front[word[0]-'0']++;            back[word[L-1]-'0']++;        }        int num1=0,num2=0;        for(int i=0;i<LEN;i++)        {            if(front[i]!=back[i])            {                if(front[i]==back[i]+1)                    num1++;                else if(front[i]+1==back[i])                    num2++;                else                {                    ok=0;                    break;                }            }        }        if(num1&&num2&&num1+num2>2)        ok=0;        if(ok){/*开头和结尾只能有一个*/        /*开始遍历!*/        int ok1=0;        int ok2=0;        for(int i=0;i<LEN;i++)        {            if(num1==0&&num2==0&&front[i])            {                /*如果是一个回路的图*/                   dfs(i);                   break;            }            else if(front[i]>back[i])            {                  dfs(i);                   break;            }        }        num1=0;num2=0;        for(int i=0;i<LEN;i++)        {            if(!vis[i]&&front[i]){ok=0;break;}            if(!vis[i]&&back[i]){ok=0;break;}        }        if(ok) printf("Ordering is possible.\n");        else printf("The door cannot be opened.\n");        }        else printf("The door cannot be opened.\n");    }    return 0;}


0 0