UVA - 10129 Play on Words

传送门:UVA - 10129

题意:输入n个单词问能否把所有单词串起来(每个单词只能用一遍),要求前一个单词的末字母与后一个单词的首字母相同

题解:可以把一个单词的末字母和首字母看成是节点,把中间的字母看成是一条路径,那么题目就转变成求一条欧拉#include <iostream>

#include <vector>
#define pb push_back
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
vector<int>vec[30];
int n;
int in[30];
int out[30];
int vis[30];void DFS(int u){
    vis[u]=0;
    for(int i=0;i<vec[u].size();i++){
        int v=vec[u][i];
        if(vis[v])DFS(v);
    }
}
int main(){
    fio;
    int t;
    cin>>t;
    while(t--){
        for(int i=0;i<30;i++)vec[i].clear(),in[i]=0,out[i]=0,vis[i]=0;
        cin>>n;
        int num=-1;
        for(int i=0;i<n;i++){
            string str;
            cin>>str;
            int u=str[0]-'a';
            int v=str[str.length()-1]-'a';
            vis[u]=1;
            vis[v]=1;
            out[u]++;
            in[v]++;
            vec[u].pb(v);
            num=u;
        }
        int flag=0;
        int l=0;
        int r=0;
        for(int i=0;i<30;i++){//判断是否满足有向图欧拉道路出入度的关系
            if(in[i]!=out[i]){
                if(in[i]-out[i]==1)l++;
                if(out[i]-in[i]==1)r++,num=i;
                if(abs(in[i]-out[i])>1)flag=1;
            }
        }
        if(flag==0&&((l==1&&r==1)||(l+r==0))){
            DFS(num);
            for(int i=0;i<30;i++){
                flag+=vis[i];
            }
        }
        if(flag){
            cout<<"The door cannot be opened.\n";
        }
        else {
            cout<<"Ordering is possible.\n";
        }
    }
    return 0;
}

 

posted @ 2018-03-16 00:07  采蘑菇的小西佬  阅读(156)  评论(0编辑  收藏  举报