zoukankan      html  css  js  c++  java
  • hdoj 1116 Play on Words 【并查集】+【欧拉路】

    Play on Words

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 5622    Accepted Submission(s): 1850


    Problem Description
    Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because there is no other way to open the doors, the puzzle is very important for us.

    There is a large number of magnetic plates on every door. Every plate has one word written on it. The plates must be arranged into a sequence in such a way that every word begins with the same letter as the previous word ends. For example, the word ``acm'' can be followed by the word ``motorola''. Your task is to write a computer program that will read the list of words and determine whether it is possible to arrange all of the plates in a sequence (according to the given rule) and consequently to open the door.
     

    Input
    The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing a single integer number Nthat indicates the number of plates (1 <= N <= 100000). Then exactly Nlines follow, each containing a single word. Each word contains at least two and at most 1000 lowercase characters, that means only letters 'a' through 'z' will appear in the word. The same word may appear several times in the list.
     

    Output
    Your program has to determine whether it is possible to arrange all the plates in a sequence such that the first letter of each word is equal to the last letter of the previous word. All the plates from the list must be used, each exactly once. The words mentioned several times must be used that number of times.
    If there exists such an ordering of plates, your program should print the sentence "Ordering is possible.". Otherwise, output the sentence "The door cannot be opened.".
     

    Sample Input
    3 2 acm ibm 3 acm malform mouse 2 ok ok
     

    Sample Output
    The door cannot be opened. Ordering is possible. The door cannot be opened.

    题意:给出几个字符串。假设一个字符串的首字符(尾子符)等于另外一个字符串的尾子符(首字符),就让他们连接起来。问最后能不能把全部的字符串都连接起来。

    分析:非常明显的是要用到并查集的仅仅是。可是处理首尾字符的时候会有点麻烦,我们最好还是将没一个字符的首尾字符都视为一个点,一个字符串就是一条边,那么该题就转化为了求边能不能形成一条连通图,之后就要用欧拉路来推断改图是否连通就好了。

    注:欧拉路分为欧拉回路和欧拉通路。

    欧拉通路:满足从一点出发经过每一条边且仅仅经过一次,能把全部的边都经过的路

    欧拉回路:欧拉通路而且最后回到原点的路;

    假设是欧拉回路那么图中每一个点的入读和处度都相等

    假设是通路那么起始点的出度减入度为1, 终点处入度减出度为1。

    代码:

    /*hdoj 1116 并查集+欧拉通/回路*/
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #define M 1005
    
    int out[26], in[26], fat[26];
    bool vis[26];
    char s[M];
    
    int f(int x){
    	if(x != fat[x]) fat[x] = f(fat[x]);
    	return fat[x];
    }
    
    void merge(int x, int y){
    	int a = f(x);
    	int b = f(y);
    	if(a != b) fat[a] = b;
    }
    
    int main(){
    	int n, t, i;
    	scanf("%d", &t);
    	while(t --){
    		memset(vis, 0, sizeof(vis));
    		memset(out, 0, sizeof(out));
    		memset(in, 0, sizeof(in));
    		scanf("%d", &n);
    		for(i = 0; i < 26; i ++) fat[i] = i;
    		for(i = 0; i < n; i ++){
    			scanf("%s", s);
    			int x = s[0]-'a';
    			int y = s[strlen(s)-1]-'a';
    			merge(x, y);
    			++out[x]; ++in[y];
    			vis[x] = vis[y] = 1;
    		}
    		int flag1 = 0;
    		for(i = 0; i < 26; i ++){  //推断是否联连通
    			if(vis[i]&&fat[i] == i) ++flag1;  
    		}
    		if(flag1 > 1){
    			printf("The door cannot be opened.
    "); continue;
    		}
    		int flag2, flag3;  //flag1是推断是否是所有出入度都相等,flag2是判读起始点有几个,flag3是终点有几个
    		flag1 = flag2 = flag3 = 0;
    		for(i = 0; i < 26; i ++){
    			if(vis[i]&&out[i] != in[i]){
    				++flag1;
    				if(out[i]-in[i] == 1) ++flag2;
    				if(in[i] - out[i] == 1) ++flag3;
    			}
    		}
    		if(flag1 == 0) printf("Ordering is possible.
    ");
    		else if(flag1 == 2&&flag2 == 1&&flag3 == 1) printf("Ordering is possible.
    ");
    		else printf("The door cannot be opened.
    ");
    	}
    	return 0;
    } 



  • 相关阅读:
    洛谷P1056_排座椅 贪心+桶排思想
    NOIP普及组相关
    洛谷P1464_Function 记忆化搜索
    Xcode的使用技巧
    MAC_XCODE清理
    输入框跟随键盘移动效果的实现
    #pragma的进阶用法
    iOS 逆向
    警告框
    UIImageView设置圆角的方式
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6782816.html
Copyright © 2011-2022 走看看