zoukankan      html  css  js  c++  java
  • Hdu-1116 Play on Words

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1116

    题目大意:给你一些英文单词,判断所有单词能不能连成一串,类似成语接龙的意思。但是如果有多个重复的单词时,也必须满足这样的条件才能算YES。否则都是不可能的情况。

    解题思路:

    欧拉路的基本题。只要知道就可以做出来了。

    定义:
    欧拉回路:每条边恰好只走一次,并能回到出发点的路径
    欧拉路径:经过每一条边一次,但是不要求回到起始点

    ①首先看欧拉回路存在性的判定:

    一、无向图
    每个顶点的度数都是偶数,则存在欧拉回路。

    二、有向图(所有边都是单向的)
    每个节顶点的入度都等于出度,则存在欧拉回路。

     三.混合图欧拉回路
      混合图欧拉回路用的是网络流。
      把该图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路。因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路。
      好了,现在每个点入度和出度之差均为偶数。那么将这个偶数除以2,得x。也就是说,对于每一个点,只要将x条边改变方向(入>出就是变入,出>入就是变出),就能保证出 = 入。如果每个点都是出 = 入,那么很明显,该图就存在欧拉回路。
      现在的问题就变成了:我该改变哪些边,可以让每个点出 = 入?构造网络流模型。首先,有向边是不能改变方向的,要之无用,删。一开始不是把无向边定向了吗?定的是什么向,就把网络构建成什么样,边长容量上限1。另新建s和t。对于入 > 出的点u,连接边(u, t)、容量为x,对于出 > 入的点v,连接边(s, v),容量为x(注意对不同的点x不同)。之后,察看是否有满流的分配。有就是能有欧拉回路,没有就是没有。欧拉回路是哪个?查看流值分配,将所有流量非 0(上限是1,流值不是0就是1)的边反向,就能得到每点入度 = 出度的欧拉图。
      由于是满流,所以每个入 > 出的点,都有x条边进来,将这些进来的边反向,OK,入 = 出了。对于出 > 入的点亦然。那么,没和s、t连接的点怎么办?和s连接的条件是出 > 入,和t连接的条件是入 > 出,那么这个既没和s也没和t连接的点,自然早在开始就已经满足入 = 出了。那么在网络流过程中,这些点属于“中间点”。我们知道中间点流量不允许有累积的,这样,进去多少就出来多少,反向之后,自然仍保持平衡。
      所以,就这样,混合图欧拉回路问题,解了。


    ②.欧拉路径存在性的判定

    一。无向图
    一个无向图存在欧拉路径,当且仅当   该图所有顶点的度数为偶数   或者  除了两个度数为奇数外其余的全是偶数

    二。有向图
    一个有向图存在欧拉路径,当且仅当 该图所有顶点的度数为零     或者 一个顶点的度数为1,另一个度数为-1,其他顶点的度数为0

    三。混合图欧拉路径
    其实整篇文章只有这部分是我写的哈,灰常不好意思,只是网上的同志们写的太好了,实在没有必要重复劳动,不知道大家有没有发现,求欧拉路径的第一步一定是求欧拉回路,在混合图上也不例外,如何判断混合图欧拉回路问题的存在性呢?首先,我们用上文所说的方法判断该图是否存在欧拉回路,如果存在,欧拉路径一定存在。如果欧拉回路不存在,那么我们枚举欧拉路径的起点和终点,连接一条无向边,然后再用最大流判断是否存在欧拉回路即可。


    所以这道题的大题思路就是:

    1.并查集判断连通

    2.将每个单词取出首字母和尾字母,转换为一条边,然后加入对应的连通分量中。如果这个字母出现过,visit数组标记为true。同时起点出度加1,终点入度加1.

    3.判断一下:

    1)这个图必须是连通的,即根结点只有一个。如果不是,直接结束本次算法。

    2)如果这个图是连通的,判断每个结点的入度和出度情况。

            如果这个图是欧拉路,则每个顶点的出度等于入度。即out[i] = in[i]

    如果这个图是半欧拉图,则起点的出度比入度大1,终点的入度比出度大1.其余顶点的出度等于入度。

    如果满足上述条件,就可以将所有单词链接起来,否则不能。

    当然,在判断出度入度的时候还有一点需要注意,那就是除了起点终点以外的顶点,出度必须等于入度(出度入度可以同时为2,即环),但是起点和终点必须保证出度和入度之差为1。


    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    #define MAXN 30
    int pre[MAXN], in[MAXN], out[MAXN];
    bool visit[MAXN];
    
    int find(int x)
    {
    	return x == pre[x] ? x : find(pre[x]);
    }
    
    void join(int x, int y)
    {
    	int root1, root2;
    	root1 = find(x);
    	root2 = find(y);
    	if(root1 != root2)
    		pre[root2] = root1;
    }
    
    int main()
    {
    	int ncase;
    	int wordnum, len; //单词个数,每个单词长度
    	int start, end; //转化为边
    	char str[1010];
    	int innum, outnum; //记录入度出度不相等顶点个数
    	int root; //根结点个数
    	bool flag; //判断连通性
    	bool flag1; //判断入度和出度是否是1或者0
    	scanf("%d", &ncase);
    	while(ncase--)
    	{
    		memset(in, 0, sizeof(in));
    		memset(out, 0, sizeof(out));
    		memset(visit, false, sizeof(visit));
    		for(int i = 1; i < MAXN; ++i)
    			pre[i] = i;
    		innum = outnum = root = 0;
    		flag = flag1 = true;
    		scanf("%d", &wordnum);
    		for(int i = 1; i <= wordnum; ++i)
    		{
    			scanf("%s", str);
    			len = strlen(str);
    			start = str[0] - 'a' + 1;
    			end = str[len - 1] - 'a' + 1;
    			visit[start] = true;
    			visit[end] = true;
    			out[start]++;
    			in[end]++;
    			join(start, end);
    		}
    		for(int i = 1; i < MAXN; ++i)
    		{		
    			if(visit[i])
    			{
    				if(pre[i] == i)
    					root++;
    				if(in[i] != out[i])
    				{
    					if(in[i] - out[i] == 1)
    						innum++;
    					else if(out[i] - in[i] == 1)
    						outnum++;
    					else 
    						flag1 = false;
    				}
    			}
    			if(root > 1)
    			{
    				flag = false;
    				break;
    			}
    		}
    		if((flag && innum == 0 && outnum == 0 && flag1) || (flag && innum == 1 && outnum == 1 && flag1))
    			printf("Ordering is possible.
    ");
    		else
    			printf("The door cannot be opened.
    ");
    	}
    	return 0;
    }

  • 相关阅读:
    软件体系架构复习要点
    Operating System on Raspberry Pi 3b
    2019-2020 ICPC North-Western Russia Regional Contest
    2019 ICPC ShenYang Regional Online Contest
    2019 ICPC XuZhou Regional Online Contest
    2019 ICPC NanChang Regional Online Contest
    2019 ICPC NanJing Regional Online Contest
    Codeforces Edu Round 72 (Rated for Div. 2)
    Codeforces Round #583 (Div.1+Div.2)
    AtCoder Beginning Contest 139
  • 原文地址:https://www.cnblogs.com/u013533289/p/4477278.html
Copyright © 2011-2022 走看看