UVA 10129-Play on Words(欧拉通路)

题意:给N个单词,判断是否单词首尾(前一个单词的尾字符与后一个单词的头字符相同)相连能否形成一条链。

解析:找欧拉通路(欧拉回路或是欧拉链路),但这题事先需要并查集一下,判断是否只属于一个集合,如aa,bb,cc不能形成一条链,但会判断成欧拉回路。

代码如下:

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<iterator>
#include<utility>
#include<sstream>
#include<iostream>
#include<cmath>
#include<stack>
using namespace std;
const int INF=1000000007;
const double eps=0.00000001;
int N,nodenum;
int d[26];
int root(int a)
{
    while(d[a]!=a) a=d[a];
    return a;
}
bool merg(int a,int b)                 //合并
{
    int ra=root(a);
    int rb=root(b);
    if(ra!=rb){ d[ra]=rb; return true; }
    return false;
}
int indeg[26],outdeg[26];     //入度,出度
bool vis[26];
char S[1005];
void input()
{
    nodenum=0;
    cin>>N;
    for(int i=1;i<=N;i++)
    {
        scanf("%s",S);
        int pre=S[0]-'a',last=S[strlen(S)-1]-'a';
        if(!vis[pre]){ vis[pre]=true; nodenum++; }   //标记并节点数加一
        if(!vis[last]){ vis[last]=true; nodenum++; }
        outdeg[pre]++;
        indeg[last]++;
        if(merg(pre,last))  nodenum--;   //减1
    }
}
bool check()                   //判断是否有欧拉通路
{
    int f1=0,f2=0;
    for(int i=0;i<26;i++)
    {
        if(indeg[i]+1==outdeg[i])  f1++;
        else if(indeg[i]==outdeg[i]+1) f2++;
        else if(indeg[i]!=outdeg[i])  return false;
    }
    if((f1==0&&f2==