NYOJ 单词拼接(求有向图的欧拉通路)


单词拼接

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 5
http://acm.nyist.net/JudgeOnline/problem.php?pid=99
描述

给你一些单词,请你判断能否把它们首尾串起来串成一串。

前一个单词的结尾应该与下一个单词的道字母相同。

aloha

dog

arachnid

gopher

tiger

rat

 

可以拼接成:aloha.arachnid.dog.gopher.rat.tiger

输入
第一行是一个整数N(0 每组测试数据的第一行是一个整数M,表示该组测试数据中有M(2
输出
如果存在拼接方案,请输出所有拼接方案中字典序最小的方案。(两个单词之间输出一个英文句号".")
如果不存在拼接方案,则输出
***
样例输入
2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm
样例输出
aloha.arachnid.dog.gopher.rat.tiger
***


此题是以字符串的首尾字母为节点的,以字符串本身为边的。

有向图判定是否存在欧拉通路,并输出欧拉路径。

有向图定理:有向图D存在欧拉通路的充要条件是:D为有向图,D的基图(就是图D对应的无向图)连通,并且每个节点的出度等于它的入度;或者除两个节点外,其他节点的出度与入度都相等,而这两个节点中,其中一个节点的出度与入度的差为1(out-in=1),另一个顶点的出度与入度之差为-1(out-in=-1)

推论:

1.   当有向图D,除了出度,入度之差为1,-1的两个节点之外,其余顶点的出度与入度相等时,D的有向欧拉通路必以出度与入度之差为1的顶点作为始点,以出度与入度之差为-1的顶点作为终点。

2.   当有向图D的所有顶点的出度与入度都相等时,D中存在有向欧拉回路。

3.   有向图D为有向欧拉图的充要条件是D的基图为连通图,并且所有节点的出、入度都相等。

因此此题的解题方法分为三步:

1.判断有向图G对应的无向图是连通的。

2.统计每个节点的入度与出度,要求所有节点的出度与入度都相等 或 其中一个节点的出度与入度的差为1,另一个节点的出度与入度之差为-1,其他顶点的出度与入度都相等。

3.满足以上两个条件,递归求欧拉路径并输出。


#include
#include
#include
#include
#include
#include
#define PI 3.1415926

using namespace std;

const int maxn = 1003;
int father[30];   ///并查集
int ans[maxn];
int in[30];       ///存放每个节点的入度
int out[30];      ///存放每个节点的出度
string word[maxn];  ///用来存放单词
int N,k;              ///单词数
int chose[30];      ///用来判断哪些小写字母出现了
struct Edge         ///以单词为边,以单词的首尾字母为节点
{
    int s;          ///起点
    int d;          ///终点
    bool flag;      ///标记当前单词是否用过
}edge[maxn];
void make_set()    ///并查集初始化
{
    for(int i = 0; i < 30; i++)
        father[i] = i;
}
int find_set(int x)  ///找x所在的集合
{
    while(x != father[x])
    {
        x = father[x];
    }
    return x;
}
void union_set(int x,int y)  ///合并两个集合
{
    father[x] = y;
}
bool IsConnection()  ///判断图是否连通
{
    int num = 0;
    ///chose用来标记图中存在哪些小写字母
    for(int i = 0; i < 26; i++)
    {
        if(chose[i])  ///是图中的节点
        {
            if(father[i]==i)
            {
                num++;
            }
        }
    }
    if(num == 1) return true;
    else return false;
}
void DFS(int start)
{
    for(int i = 0; i < N; i++)
    {
        if(edge[i].s == start)
        {
            if(!edge[i].flag)
            {
                edge[i].flag = true;
                DFS(edge[i].d);
                ans[k++] = i;
                ///求出后答案是倒着的
            }
        }
    }
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>N;         ///N个单词
        for(int i = 0; i < N; i++)
        {
            cin>>word[i];
        }
        memset(chose,0,sizeof(chose));  ///题目中出现的单词
        memset(out,0,sizeof(out));      ///各个点的入度赋值为0
        memset(in,0,sizeof(in));        ///各个点的出度赋值为0
        make_set();
        ///因为答案最后要的是字典序最小的,因此要先对字符排序。
        sort(word,word+N);
        for(int i = 0; i < N; i++)
        {
            int len = word[i].length();
            int s = word[i][0]-'a';
            int d = word[i][len-1]-'a';
            chose[s] = chose[d] = 1;
            edge[i].s = s;
            edge[i].d = d;
            edge[i].flag = false;
            out[s]++;
            in[d]++;
            int fs = find_set(s);
            int fd = find_set(d);
            if(fs != fd)
                union_set(fs,fd);
        }
        int start = edge[0].s;  ///假设起点是这个字符
        int num1 = 0,num2 = 0;  
        bool flag = true;
        for(int i = 0; i < 26; i++)
        {
            if(chose[i])
            {
                if(in[i]==out[i]) continue;
                else if(out[i]-in[i]==1)
                {
                    start = i;
                    num1++;
                }
                else if(out[i]-in[i]==-1)
                {
                    num2++;
                }
                else
                {
                    flag = false;
                    break;
                }
            }
        }
        ///三个条件都成立,欧拉通路存在。
        if(flag&&((num1==0&&num2==0)||(num1==1&&num2==1))&&IsConnection())
        {
            k = 0;
            DFS(start);
            cout<= 0; i--)
            {
                cout<<"."<


你可能感兴趣的:(ACM_并查集,ACM_图论)