• POJ 2337 【欧拉路径<包含输出>】.cpp


    题意:

      给出n个字母

      问是否可以全部头尾相接,输出按字典序排列

    思路:

      用套圈法求出欧拉回路

          先把单词读入

          排序保证最后结果是按字典序的

          用并查集看是否连通

          根据入度和出度看是否是欧拉路径,如果有必要也要找出起点

          用套圈法求出欧拉路径

          输出结果  

    Tips:

      ※ 不能用cin cout

          注意不能直接由 ansi == n 来判断是否有欧拉路径..

            而要由出度和入度的关系来判断..

            因为如果出现是出度-入度 = 1 且 入度-出度 = 1的时候要保证 出度-入度 = 1的点是起点~
            否则即使连通也不能证明存在欧拉路径..

            ※ 用并查集检查是否连通以及从每一个已知的起点开始dfs的时候可以for(i : a~z)而不是for(i: 0~n)

                这样可以降低时间复杂度~~

    Code:

    View Code
      1 #include <stdio.h>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 const int MAXN = 1010;
      6 #define clr(x) memset(x, 0, sizeof(x));
      7 #define INF 0x1f1f1f1f
      8 
      9 struct Edge
     10 {
     11     int to;
     12     int next;
     13 
     14 }edge[1000000];
     15 int tot;
     16 int head[MAXN];
     17 
     18 void add(int s, int u)
     19 {
     20     edge[tot].to = u;
     21     edge[tot].next = head[s];
     22     head[s] = tot++;
     23 }
     24 
     25 struct Inf
     26 {
     27     char arr[25];
     28     bool operator < (const Inf&a) const {
     29         return strcmp(arr, a.arr) > 0;
     30     }
     31 }inf[MAXN];
     32 
     33 bool vis[MAXN];
     34 int ans[MAXN], ansi;
     35 void dfs(int x) {
     36     for(int i = head[x]; i; i = edge[i].next) {
     37         if(!vis[i]) {
     38             vis[i] = true;
     39             dfs(edge[i].to);
     40             ans[ansi++] = i;
     41         }
     42     }
     43 }
     44 
     45 int pre[26];
     46 bool v[26];
     47 int in[26], out[26];
     48 int find(int x)
     49 {
     50     return pre[x] == x?x:(pre[x] = find(pre[x]));
     51 }
     52 
     53 void ini()
     54 {
     55     clr(head);
     56     tot = 1;
     57  //  memset(head, 0xff, sizeof(head));
     58  //  tot = 0;
     59     clr(vis);
     60     ansi = 0;
     61     for(int i = 0; i < 26; ++i)
     62         pre[i] = i;
     63     clr(v);
     64     clr(in);
     65     clr(out);
     66 }
     67 
     68 int main()
     69 {
     70   //  freopen("e:\\acm\\in.txt", "r", stdin);
     71     int T, n;
     72     int a, b, len;
     73     bool flag;
     74     int _f, _ff, _fff, r;
     75     while(EOF != scanf("%d", &T))
     76     while(T--) {
     77         scanf("%d", &n);
     78         ini();
     79         flag = true;
     80         for(int i = 0; i < n; ++i)
     81             scanf("%s", inf[i].arr);
     82 
     83         sort(inf, inf+n);
     84         for(int i = 0; i < n; ++i) {
     85             len = strlen(inf[i].arr);
     86             a = inf[i].arr[0]-'a', b = inf[i].arr[len-1]-'a';
     87             add(a, b);
     88             in[b]++, out[a]++, v[a] = v[b] = true;
     89             int fa = find(a);
     90             int fb = find(b);
     91             if(fa < fb) pre[fb] = fa;
     92             else pre[fa] = fb;
     93         }
     94         _f = -1;
     95         for(int i = 0; i < 26; ++i)
     96         if(v[i] && _f == -1) _f = find(i);
     97         else if(v[i] && _f != find(i)) {
     98             flag = false;
     99             break;
    100         }
    101         if(!flag) {
    102             puts("***");
    103             continue;
    104         }
    105         _f = 0, _ff = 0, _fff = 0;
    106         for(int i = 0; i < 26; ++i)
    107         if(v[i]) {
    108             if(in[i]-out[i] == 1) _f++;
    109             else if(out[i]-in[i] == 1) {
    110                 r = i;
    111                 _ff++;
    112             } else if(out[i] != in[i]) _fff++;
    113         }
    114         if(_fff == 0 && _f == 1 && _ff == 1) {
    115             dfs(r);
    116             for(int i = ansi-1; i >= 0; --i)
    117                 printf("%s%c", inf[ans[i]-1].arr, i == 0?'\n':'.');
    118         } else if(_fff == 0 && _f == 0 && _fff == 0) {
    119             int i;
    120             for(i = 0; i < 26; ++i)
    121             if(v[i]) break;
    122             dfs(i);
    123             for(int i = ansi-1; i >= 0; --i)
    124                 printf("%s%c", inf[ans[i]-1].arr, i == 0?'\n':'.');
    125         } else puts("***");
    126     }
    127     return 0;
    128 }

    链接:http://poj.org/problem?id=2337

  • 相关阅读:
    BZOJ5212 ZJOI2018历史(LCT)
    BZOJ5127 数据校验
    253. Meeting Rooms II
    311. Sparse Matrix Multiplication
    254. Factor Combinations
    250. Count Univalue Subtrees
    259. 3Sum Smaller
    156. Binary Tree Upside Down
    360. Sort Transformed Array
    348. Design Tic-Tac-Toe
  • 原文地址:https://www.cnblogs.com/Griselda/p/2888857.html
Copyright © 2020-2023  润新知