zoukankan      html  css  js  c++  java
  • uva-10129-欧拉通路

    题意:每一个单词的长度最小2,最大1000,单词开头的字母和另外一个单词的末尾一样就可以连接起来,解所有的单词是不是都可以连接起来,没有遗漏的

    把每一个单词的第一个字母当成一个结点,最后一个单词也作为一个结点,表示第一个字母有一条路径走到最后一个单词,题目的意思就转化为,单词开头字母和结尾

    字母组成的图是不是一个联通图,并且这个图存在欧拉通路.

    欧拉通路判定(不一定是成环),图中只有俩个结点的度是奇数,终点的入度比出度大1,起点的出度比入度大1,其他点的入度必须等于出度.

    欧拉通路的判断+起点和终点的出度等于入度那就是欧拉回路了,但是这个题只要判断通路.

    使用了并查集判断图是否联通.

    AC时间:30ms

    #include <iostream>
    #include<stdio.h>
    #include<math.h>
    #include<memory.h>
    using namespace std;
    
    
    int const max = 'z';
    int const min = 'a';
    int const length = 'z' - 'a' + 1;
    void _init(int *a, int length);
    int find(int key, int *a);
    void join(int k1, int k2, int *a);
    
    int main()
    {
    	freopen("d:\1.txt", "r", stdin);
    	int c;
    	cin >> c;
    	string yes = "Ordering is possible.";
    	string no = "The door cannot be opened.";
    	while (c--)
    	{
    		int n;
    		cin >> n;
    		string str;
    		if (n == 1)
    		{
    			cin >> str;
    			cout << yes << endl;
    			continue;
    		}
    		int set[length];
    		int duIn[length];
    		int duOut[length];
    		int vis[length];
    		memset(vis, 0, sizeof(vis));
    		memset(duIn, 0, sizeof(duIn));
    		memset(duOut, 0, sizeof(duIn));
    		_init(set, length);
    		while (n--)
    		{
    			cin >> str;
    			int s, e;
    			s = str[0];
    			s -= 'a';
    			e = str[str.length() - 1];
    			e -= 'a';
    			duOut[s]++;
    			duIn[e]++;
    			vis[s] = 1;
    			vis[e] = 1;
    			join(s, e, set);
    		}
    		//判断度和根结点
    		int p = -1;
    		int s = 0;
    		int ok = 1;
    		for (int i = 0; i < length; i++)
    		{
    			if (!vis[i])
    				continue;
    			int key = find(i, set);
    			if (p == -1)
    			{
    				p = key;
    			}
    			else if (key != p)
    			{
    				ok = 0;
    				break;
    			}
    			if (duIn[i] != duOut[i])
    			{
    				int t = duIn[i] - duOut[i];
    				if ((t == -1 || t == 1) && (s <= 1))
    				{
    					t++;
    				}
    				else
    				{
    					ok=0;
    					break;
    				}
    			}
    		}
    		if (ok)
    			cout << yes << endl;
    		else
    			cout << no << endl;
    
    	}
    	return 0;
    }
    
    void join(int k1, int k2, int* a)
    {
    	int p1 = find(k1, a);
    	int p2 = find(k2, a);
    	if (p1 != p2)
    		a[p1] = p2;
    }
    
    int find(int key, int *a)
    {
    	return key == a[key] ? key : a[key] = find(a[key], a);
    }
    
    void _init(int* a, int length)
    {
    	for (int i = 0; i < length; i++)
    		a[i] = i;
    }
    

      

  • 相关阅读:
    UISegmentControl
    UISegmentControl,UISwich,UIPageControl
    UIPageControl,UISlider
    UISlider
    触摸事件,响应者链和手势
    NIO Socket
    处理多线程问题的工具类
    Java多线程疑难点
    软中断和硬中断的联系与区别
    进程—内存描述符(mm_struct)
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/7111699.html
Copyright © 2011-2022 走看看