zoukankan      html  css  js  c++  java
  • poj 2337 之 有向图 欧拉路径输出

    /*
    poj 2337 之 有向图 欧拉路径输出 
     
    每个单词看作一条有向边,顶点即为单词首尾字母,然后求欧拉路径即可。
     
    1)为保证字典序,先对单词按字典序排序
    2)深搜,输出单词序列
    */
      1 #include <iostream>
      2 #include <fstream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstdio>
      6 #include <cstddef>
      7 #include <iterator>
      8 #include <algorithm>
      9 #include <string>
     10 #include <locale>
     11 #include <cmath>
     12 #include <vector>
     13 #include <cstring>
     14 #include <map>
     15 #include <utility>
     16 #include <queue>
     17 #include <stack>
     18 #include <set>
     19 #include <functional>
     20 using namespace std;
     21 typedef pair<int, int> PII;
     22 typedef long long int64;
     23 const int INF = 0x3f3f3f3f;
     24 const int modPrime = 3046721;
     25 const double eps = 1e-9;
     26 const int MaxN = 1010;
     27 const int MaxM = 30;
     28 const char Opt[4] = { '+', '-', '*', '/' };
     29 
     30 int n;
     31 
     32 struct Edge
     33 {
     34     int to;
     35     int nextEdge;
     36     int index;
     37     bool isVisited;
     38 };
     39 Edge edge[MaxN];
     40 int head[MaxM];
     41 
     42 int startPot = INF;
     43 int in[MaxM];
     44 int out[MaxM];
     45 vector<string> wordVec;
     46 vector<int> eulerPath;
     47 
     48 int total = 0;
     49 
     50 
     51 //Union-Find Sets
     52 int ftr[MaxM];
     53 int rnk[MaxM];
     54 void ufsIni()
     55 {
     56     for (int i = 0; i < MaxM; ++i)
     57     {
     58         ftr[i] = i;
     59         rnk[i] = 0;
     60     }
     61 }
     62 int ufsFind(int x)
     63 {
     64     if (x == ftr[x]) return x;
     65     return ftr[x] = ufsFind(ftr[x]);
     66 }
     67 void ufsUnite(int x, int y)
     68 {
     69     x = ufsFind(x);
     70     y = ufsFind(y);
     71     if (x == y) return;
     72 
     73     if (rnk[x] > rnk[y])
     74     {
     75         ftr[y] = x;
     76     }
     77     else
     78     {
     79         ftr[x] = y;
     80         if (rnk[x] == rnk[y])
     81         {
     82             ++rnk[y];
     83         }
     84     }
     85 }
     86 
     87 void addEdge(int u, int v, int index)
     88 {
     89     edge[total].to = v;
     90     edge[total].index = index;
     91     edge[total].nextEdge = head[u];
     92     edge[total].isVisited = false;
     93     head[u] = total++;
     94 }
     95 
     96 
     97 bool isExistEulerpath(int n)
     98 {
     99     
    100     ufsIni();
    101     for (int i = 0; i < n; ++i)
    102     {
    103         string word;
    104         cin >> word;
    105         wordVec.push_back(word);
    106     }
    107     sort(wordVec.begin(), wordVec.end(), greater<string>());
    108     set<int> potSet;
    109     for (int i = 0; i < n; ++i)
    110     {
    111         string word = wordVec[i];
    112         int fromCh = word[0] - 'a', toCh = word[word.size() - 1] - 'a';
    113         ++out[fromCh];
    114         ++in[toCh];
    115         addEdge(fromCh, toCh, i);
    116         potSet.insert(fromCh);
    117         potSet.insert(toCh);
    118         startPot = min(startPot, min(fromCh, toCh));
    119         ufsUnite(fromCh, toCh);
    120     }
    121     for (set<int>::iterator it = potSet.begin(); it != potSet.end(); ++it)
    122     {
    123         if (ufsFind(ftr[*it]) != ufsFind(ftr[*(potSet.begin())]))
    124         {
    125             return false;
    126         }
    127     }
    128     int tmpU = 0, tmpV = 0;
    129     for (set<int>::iterator it = potSet.begin(); it != potSet.end(); ++it)
    130     {
    131         if (out[*it] - in[*it] == 1)
    132         {
    133             ++tmpU;
    134             if (tmpU > 1)
    135             {
    136                 return false;
    137             }
    138             startPot = *it;
    139         }
    140         else
    141         {
    142             if (out[*it] - in[*it] == -1)
    143             {
    144                 ++tmpV;
    145                 if (tmpV > 1)
    146                 {
    147                     return false;
    148                 }
    149             }
    150             else
    151             {
    152                 if (out[*it] - in[*it] != 0)
    153                 {
    154                     return false;
    155                 }
    156             }
    157         }
    158     }
    159     if (!((0 == tmpU && 0 == tmpV) || (1 == tmpU && 1 == tmpV)))
    160     {
    161         return false;
    162     }
    163     return true;
    164 }
    165 
    166 
    167 void Solve(int pos)
    168 {
    169     for (int i = head[pos]; i != -1; i = edge[i].nextEdge)
    170     {
    171         if (!edge[i].isVisited)
    172         {
    173             edge[i].isVisited = true;
    174             Solve(edge[i].to);
    175             eulerPath.push_back(edge[i].index);
    176         }
    177     }
    178 }
    179 
    180 int main()
    181 {
    182 #ifdef HOME
    183     freopen("in", "r", stdin);
    184     //freopen("out", "w", stdout);
    185 #endif
    186     
    187     int T;
    188     cin >> T;
    189     while (T--)
    190     {
    191         startPot = INF;
    192         total = 0;
    193         fill(head, head + MaxM, -1);
    194         fill(in, in + MaxM, 0);
    195         fill(out, out + MaxM, 0);
    196         cin >> n;
    197         if (isExistEulerpath(n))
    198         {
    199             Solve(startPot);
    200             for (vector<int>::reverse_iterator rIt = eulerPath.rbegin(); rIt != eulerPath.rend(); ++rIt)
    201             {
    202                 cout << wordVec[*rIt];
    203                 if (rIt != eulerPath.rend() - 1)
    204                 {
    205                     cout << ".";
    206                 }
    207                 else
    208                 {
    209                     cout << endl;
    210                 }
    211             }
    212         }
    213         else
    214         {
    215             cout << "***" << endl;
    216         }
    217         wordVec.clear();
    218         eulerPath.clear();
    219     }
    220     
    221 
    222 #ifdef HOME
    223     cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
    224     _CrtDumpMemoryLeaks();
    225 #endif
    226     return 0;
    227 }
    
    
    
     
    
    
    
     
  • 相关阅读:
    nmap 快速扫描所有端口
    cdh ntpdate 问题
    看22是不是被玻璃破解
    lucas定理
    HDU1398--Square Coins(母函数)
    【转】HDU1028
    【转】母函数(Generating function)详解 — TankyWoo(红色字体为批注)
    HDU--1085--Holding Bin-Laden Captive!(母函数)
    HDU2588--GCD(欧拉函数)
    【转】扩展欧几里德
  • 原文地址:https://www.cnblogs.com/shijianming/p/5104242.html
Copyright © 2011-2022 走看看