Play on Words(并查集+欧拉路)

转载 2015年07月07日 17:00:50


这个题目要运用到欧拉路得相关知识,并且也要并查集,题目说的是:给你n个单词,要你判断这些单词能不能首尾相连。理解题目意思后,进行转化,输入字符串,提取首位字母作为下标来表示两节点的出现,以及相对应节点入度和出度的增加,转化为并查集的应用即可。那么从可以想象一幅由首位字母节点构成的图,当且仅当图是一条欧拉回路或者欧拉通路的时候,才能满足题目的要求,至于欧拉回路和欧拉通路的判定可以总结为如下:
1)所有的点联通
2)欧拉回路中所有点的入度和出度一样。

3)欧拉通路中起点的入度 - 出度 = 1,终点的 初度 - 入度 = 1, 其他的所有点入度 = 出度;

无向图存在欧拉回路条件

  一个无向图存在欧拉回路,当且仅当该图所有顶点度数都是偶数。

有向图存在欧拉回路条件

  一个有向图存在欧拉回路,且所有顶点的入度等于出度


这里我把单词的头作为出度单词的尾作为入度,其实都一样!


#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
const int N=30;
using namespace std;
int a[N];//记录老大是谁?
int in[N];//记录入读!
int out[N];//记录出度!
int vis[N];//记录是否访问!
int p[30];//记录头和尾
int Find(int x)
{
    int r=x;
    while(r!=a[r])
        r=a[r];
    return r;
}//这个就是找老大的函数,什么时候停止?就是当一个人的老大是他自己的时候!
void mix(int x,int y)
{
    int fx=Find(x),fy=Find(y);//首先要找到他们各自的老大
    if(fx!=fy)//如果他们的老大不相等,要合并就必须其中的一个老大向另外一个老大称老大
    {
        a[fy]=fx;
    }
}
int main()
{
    int t,n,i,f,j,l,c,b;
    string s;
    cin>>t;
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        memset(out,0,sizeof(out));
        memset(in,0,sizeof(in));
        for(i=0;i<N;i++)
        {
            a[i]=i;
        }
        cin>>n;
        for(i=0;i<n;i++)
        {
            cin>>s;
            l = s.length();
            b = s[0]-'a';
            c = s[l-1]-'a';
            out[b]++;
            in[c]++;
            vis[b]=vis[c]=1;
            mix(b,c);
        }
        for(i=0,j=0,f=0;i<N;i++)
        {
            if(vis[i]&&Find(i)==i)
            {
                f++;
            }
            if(in[i]!=out[i])//出度不等于入读!
            {
                p[j++]=i;
            }
        }
        if(f>1)
        {
            cout<<"The door cannot be opened."<<endl;
            continue;
        }
        if(j==0)
        {
            cout<<"Ordering is possible."<<endl;//欧拉通路!
            continue;
        }
        if(j==2)
        {
            if((in[p[0]]-out[p[0]]==1&&out[p[1]]-in[p[1]]==1)||(in[p[1]]-out[p[1]]==1&&out[p[0]]-in[p[0]]==1))
            {
                cout<<"Ordering is possible."<<endl;//欧拉回路!
            }
            else
            {
                cout<<"The door cannot be opened."<<endl;
            }
        }
        else
        {
            cout<<"The door cannot be opened."<<endl;
        }
    }
}


相关文章推荐

hdoj 1116 Play on Words 【并查集】+【欧拉路】

Play on Words Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others...

HDu1116——Play on Words(并查集+欧拉路径)

Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to s...

HDU 1116 && UVA 10129 && POJ 1386 ------ Play on Words(欧拉路径 + 并查集)

题意:词语接龙,看看所有单词能不嫩首尾相连, 其实就是一笔画问题,欧拉路径。 解题思路:首位字母映射为数字。变成从首至尾的一条有向边,加入并查集,使用并查集进行判断连通性。...
  • qwe585p
  • qwe585p
  • 2015年09月02日 10:51
  • 186

UVA - 10129 - Play on Words <欧拉道路+并查集>

Play on Words Some of the secret doors contain a very interesting word puzzle. The team of archaeol...
  • kun768
  • kun768
  • 2015年01月27日 11:53
  • 399

HDOJ 1116-Play on Words【欧拉路径+欧拉回路+并查集】

Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to s...

hdu 1116 Play on Word【并查集+欧拉路判断】

Play on Words Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T...

poj 1386 Play on Words(欧拉回路&&并查集)(中等)

题意: 给你一些字符串,这些字符串可以首位相接(末位置如果和另一个字符串的首位置相同的话就可以相连) 。然后问你是否可以全部连起来。 思路: 取出每个字符串的首尾字母-‘a'并保存在数组里,然后求...

Play on Words(欧拉回路+并查集)

Play on Words Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11628 Accepte...

HDU1116-Play On Words 并查集,欧拉回路

HDU1116 - Play On Words 并查集,欧拉回路

POJ 1386 Play On Words 【并查集】

原题地址:点击打开链接 其实本来想做关于欧拉回路的题的,不知道SOJ哪题是欧拉回路的,GOOGLE一下发现说POJ的1386要用欧拉回路。 但是吧……但是吧我怎么做就怎么感觉这题不是欧拉回路。 ...
  • fanfanK
  • fanfanK
  • 2013年06月06日 15:43
  • 946
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Play on Words(并查集+欧拉路)
举报原因:
原因补充:

(最多只允许输入30个字)