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;
    	}
    }


  • 相关阅读:
    UPC-5930 Rest Stops(水题)
    UPC-6199 LCYZ的道路(贪心)
    UPC-6198 JL的智力大冲浪(简单贪心)
    POJ 3279 Filptile dfs
    hrbust 1621 迷宫问题II 广搜
    HDU 1045 dfs + 回溯
    优先队列基本用法
    树。森林。和二叉树之间的转换
    POJ 2689 筛法求素数
    哈理工OJ 1328
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789393.html
Copyright © 2011-2022 走看看