Uva 10129 单词

题目链接:https://uva.onlinejudge.org/external/101/10129.pdf

 

把单词的首字母和最后一个字母看做节点,一个单词就是一个有向边。有向图的欧拉定理,就是除了起点和终点外,其他的点,出度等于入度,而且,起点和终点的出度和入度相差 1 ,这个在上一篇文章中证明了。

然后就是查连通:

1、DFS  ——从一个点出发,搜索所有相邻的边,继续dfs(v)并标记,最后查图,是不是所有点都标记了。

2、并查集 ——最多有26个块,有一条新边来了,并且,祖先不同,就相连,并且,块减 1 ,最后排除那些没有出现的点后,看是不是只有一个块了。

#include <bits/stdc++.h>
using namespace std;

const int Maxn = 1000;

int father[Maxn];
int degree[Maxn];
int used[Maxn];

int Find_Set(int x)
{
    if(x!=father[x])
        father[x] = Find_Set(father[x]);
    return father[x];
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d",&n);
        char str[1005];

        memset(used,0,sizeof(used));
        memset(degree,0,sizeof(degree));

        for(int a='a';a<='z';a++)
            father[a] = a;

        int flag = 26;

        for(int i=0;i<n;i++) {
            scanf("%s",str);

            char c1 = str[0];
            char c2 = str[strlen(str)-1];

            used[c1] = used[c2] = 1;

            degree[c1] ++;
            degree[c2] --;

            int fx = Find_Set(c1);
            int fy = Find_Set(c2);

            if(fx!=fy) {
                father[fy] = fx;
                flag --;
            }
        }

        vector<int> vaj;
        for(int a = 'a';a<='z';a++)
            if(!used[a])
                flag--;
            else {
                if(degree[a]!=0)
                    vaj.push_back(degree[a]);
            }
        sort(vaj.begin(),vaj.end());

        if(flag!=1)
            puts("The door cannot be opened.");
        else if(vaj.size()==0||(vaj.size()==2&&vaj[0]==-1&&vaj[1]==1))
            puts("Ordering is possible.");
        else puts("The door cannot be opened.");

    }
    return 0;
}

 

转载于:https://www.cnblogs.com/TreeDream/p/6051691.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值