zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    单层感知机实现或运算
    Ubuntu关于eclipse新插件不显示的解决方案
    台州学院maximum cow训练记录
    利用矩阵快速幂转换的题目
    A Few Laughing Men
    TOJ1196: RSA Signing
    HDU
    2018“百度之星”程序设计大赛
    2018 “百度之星”程序设计大赛
    2018 “百度之星”程序设计大赛
  • 原文地址:https://www.cnblogs.com/Xycdada/p/7374208.html
Copyright © 2011-2022 走看看