zoukankan      html  css  js  c++  java
  • UVA

    /*
      把字母看作结点,单词看成有向边,则,问题有解,当且仅当图中有欧拉路径
      
      存在欧拉道路的条件,见小白书 P169
      
      判断连通的方法有两种: 1. DFS 2. 并查集
    */


    #include <iostream>
    #include <vector>
    #include <string>
    #include <cstring>
    using namespace std;
    
    const int N = 256;
    
    int used[N]; // 是否出现过
    int deg[N]; // 度数 
    
    int pa[N];
    int find ( int x )
    {
    	return pa[x] != x ? pa[x] = find (pa[x]) : x;
    }
    
    void init() //初始化数组,初始化并查集 
    {
    	memset( used, 0, sizeof(used) );
    	memset( deg, 0, sizeof(deg) );
    	
    	for (int ch = 'a'; ch <= 'z'; ch++)
    	pa[ch] = ch;
    }
    
    int main()
    {
    	int t;
    	cin >> t;
    	
    	while (t--)
    	{
    		int n;
    		string word;
    		
    		cin >> n;
    		init();
    		int cc = 26; // 连通块个数
    		
    		for (int i = 0; i < n; i++)
    		{
    			cin >> word;
    			char c1 = word[0], c2 = word[ (int)word.size() - 1];
    			deg[c1]++;
    			deg[c2]--;
    			used[c1] = used[c2] = 1;
    			int s1 = find(c1), s2 = find(c2);
    			if (s1 != s2)
    			{
    				pa[s1] = s2;
    				cc--;
    			}
    		}
    		
    		vector<int> v;
    		for (int ch = 'a'; ch <= 'z'; ch++)
    		{
    			if (!used[ch]) cc--; //没出现过的字母
    			else if (deg[ch] != 0) v.push_back(deg[ch]); 
    		}
    		
    		bool ok = false;
    		if ( cc == 1 && ( v.empty() || ( v.size() == 2 && ( v[0] == 1 || v[0] == -1) ) ) ) ok = true;
    		
    		if (ok) cout << "Ordering is possible.";
    		else cout << "The door cannot be opened.";
    		cout << endl;
    	}
    }


  • 相关阅读:
    【模板】线段树(区间加)
    【模板】树状数组(区间修改+单点查询)
    【模板】并查集
    【模板】最小生成树
    LOJ #10130 点的距离
    【模板】最近公共祖先(LCA)
    【模板】树状数组
    【模板】堆
    LeetCode 242 Valid Anagram
    LeetCode 171 Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789393.html
Copyright © 2011-2022 走看看