• hdu 1116 欧拉通路+并查集


    题意:给你一些英文单词,判断所有单词能不能连成一串,前一个单词的最后一个字母和后一个单词的首字母相同则可以相连。
     

    判断是否构成欧拉回路或者欧拉通路(以下是别人博客里的一段)

    1.并查集判断连通

    2.将每个单词取出首字母和尾字母,转换为一条边,然后加入对应的连通分量中。如果这个字母出现过,visit数组标记为true。同时起点出度加1,终点入度加1.

    3.判断一下:

    1)这个图必须是连通的,即根结点只有一个。如果不是,直接结束本次算法

    2)如果这个图是连通的,判断每个结点的入度和出度情况。

            如果这个图是欧拉路,则每个顶点的出度等于入度。即out[i] = in[i]

    如果这个图是半欧拉图,则起点的出度比入度大1,终点的入度比出度大1.其余顶点的出度等于入度。

    如果满足上述条件,就可以将所有单词链接起来,否则不能。

    当然,在判断出度入度的时候还有一点需要注意,那就是除了起点终点以外的顶点,出度必须等于入度(出度入度可以同时为2,即环),但是起点和终点必须保证出度和入度之差为1。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cmath>
      4 #include<vector>
      5 #include<string.h>
      6 #include<string>
      7 
      8 using namespace std;
      9 
     10 const int MAX_N = 30;
     11 int pre[MAX_N],father[MAX_N];
     12 int iin[MAX_N],oout[MAX_N];
     13 bool visited[MAX_N];
     14 int n;
     15 
     16 void init()
     17 {
     18     for(int i = 0; i < MAX_N; i++)
     19     {
     20         pre[i] = i;
     21         iin[i]=0;
     22         oout[i]=0;
     23         father[i] = 0;
     24         visited[i]=0;
     25     }
     26 }
     27 
     28 int find_root(int x)
     29 {
     30     int r = x;
     31     while(pre[r]!=r)
     32         r = pre[r];
     33     
     34     int i = x,j;
     35     while(i!=r)
     36     {
     37         j = pre[i];
     38         pre[i] = r;
     39         i = j;
     40     }
     41     return r;
     42 }
     43 
     44 void mix(int x,int y)
     45 {
     46     int xx = find_root(x);
     47     int yy = find_root(y);
     48     if(xx!=yy)
     49         pre[yy] = xx;
     50 }
     51 int main()
     52 {
     53     cin.sync_with_stdio(false);
     54     int t,st,en;
     55     cin>>t;
     56     while(t--)
     57     {
     58         init();
     59         cin>>n;
     60         string s;
     61         for(int i = 1; i <= n; i++)
     62         {
     63             cin>>s;
     64             st = s[0]-'a';
     65             en = s[s.length()-1]-'a';
     66             mix(st,en);
     67             oout[st]++;
     68             iin[en]++;
     69             visited[st]=1;
     70             visited[en]=1;
     71         }
     72        
     73         for(int i = 0; i < 26; i++)
     74         {
     75             if(visited[i])
     76                 father[i] = find_root(i);
     77         }
     78         int ii = 0,oo = 0, flag = 0,roots = 0,te = 0;
     79         for(int i = 0; i < 26; i++)
     80         {
     81             if(visited[i])
     82             {
     83                 if(iin[i]!=oout[i])
     84                 {
     85                     if(iin[i]-oout[i]==1)
     86                         ii++;
     87                     else
     88                         if(oout[i]-iin[i]==1)
     89                             oo++;
     90                     else
     91                     {
     92                         te++;
     93                     }
     94                 }
     95                 if(father[i]==i)
     96                     roots++;
     97                 
     98             }
     99         }
    100         if(roots==1 &&((ii==0 && oo==0 && te==0)|| (ii==1 && oo==1 && te==0)))
    101             flag = 1;
    102         if(flag==1)
    103             cout<<"Ordering is possible."<<endl;
    104         else
    105             cout<<"The door cannot be opened."<<endl;
    106             
    107         
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    match、match_phrase、term示例
    AVL树及java实现
    eclipse集成lombok注解不起作用
    红黑树原理详解
    为什么HashMap中链表长度超过8会转换成红黑树
    用deepin堆砌工作环境
    为什么黑客都不用鼠标?你听说过Linux吗?
    为什么二流程序员都喜欢黑php?
    看Linux 之父是如何定义 Linux?
    Linux 系统故障排查和修复技巧
  • 原文地址:https://www.cnblogs.com/Xycdada/p/7374208.html
Copyright © 2020-2023  润新知