zoukankan      html  css  js  c++  java
  • POJ 2337 Catenyms

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

    题意:

    判断给出的单词能否首尾相连,输出字典序最小的欧拉路径。

    思路:

    因为要按字典序大小输出路径,所以先将字符串排序,这样加边的时候就会优先加字典序小的边,dfs的时候也就会先走字典序小的边。

    判断一下图的连通性以及是否存在欧拉道路。

    然后进行深搜寻找欧拉路径,因为欧拉路径时要逆序输出的,所以这里需要先保存起来,最后再次逆序输出即可得到正确的路径。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<sstream>
      6 #include<vector>
      7 #include<stack>
      8 #include<queue>
      9 #include<cmath>
     10 #include<map>
     11 #include<set>
     12 using namespace std;
     13 typedef long long ll;
     14 typedef long long ull;
     15 typedef pair<int,int> pll;
     16 const int INF = 0x3f3f3f3f;
     17 const int maxn = 1000 + 5;
     18 
     19 struct Edge
     20 {
     21     int ID;
     22     int v;
     23     int vis;
     24     Edge(){}
     25     Edge(int id,int x,int y):ID(id),v(x),vis(y){}
     26 };
     27 
     28 int n;
     29 int p[30];
     30 int in[30], out[30];
     31 string str[maxn];
     32 
     33 vector<Edge> G[maxn];
     34 
     35 stack<int> sta;
     36 
     37 int Find(int x)
     38 {
     39     return p[x]==x?x:p[x]=Find(p[x]);
     40 }
     41 
     42 void Fleury(int u)
     43 {
     44     for(int i=0;i<G[u].size();i++)
     45     {
     46         if(!G[u][i].vis)
     47         {
     48             G[u][i].vis=1;
     49             Fleury(G[u][i].v);
     50             sta.push(G[u][i].ID);   //这儿是逆序存储
     51         }
     52     }
     53 }
     54 
     55 int main()
     56 {
     57     //freopen("in.txt","r",stdin);
     58     int T;
     59     scanf("%d",&T);
     60     while(T--)
     61     {
     62         memset(in,0,sizeof(in));
     63         memset(out,0,sizeof(out));
     64 
     65         scanf("%d",&n);
     66         for(int i=0;i<26;i++)  {G[i].clear();p[i]=i;}
     67 
     68         for(int i=0;i<n;i++)   cin>>str[i];
     69         sort(str,str+n);  //排序,按照字典序顺序加边,这样等下dfs的时候就会先选择字典序小的边
     70 
     71         int start;
     72         for(int i=0;i<n;i++)
     73         {
     74             int a=str[i][0]-'a';
     75             int b=str[i][str[i].size()-1]-'a';
     76             out[a]++;
     77             in[b]++;
     78             int x=Find(a);
     79             int y=Find(b);
     80             if(x!=y)  p[x]=y;
     81             G[a].push_back(Edge(i,b,0));
     82             if(i==0)  start=a;
     83         }
     84 
     85         int cnt=0;
     86         int num1=0,num2=0,num3=0;
     87         for(int i=0;i<26;i++)
     88         {
     89             if((in[i]||out[i]) && p[i]==i)  cnt++;
     90             if(in[i]!=out[i])
     91             {
     92                 if(out[i]-in[i]==1)   {start=i;num1++;}
     93                 else if(out[i]-in[i]==-1)   num2++;
     94                 else num3++;
     95             }
     96         }
     97 
     98         if(!num3 && ((num1==0 && num2==0) || (num1==1 && num2==1)) && cnt==1)
     99         {
    100             Fleury(start);
    101             cout<<str[sta.top()]; sta.pop();
    102             while(!sta.empty())
    103             {
    104                 cout<<"."<<str[sta.top()];
    105                 sta.pop();
    106             }
    107             cout<<endl;
    108         }
    109         else {puts("***");continue;}
    110     }
    111 }
  • 相关阅读:
    jquery animate()方法 语法
    jquery unload方法 语法
    jquery undelegate()方法 语法
    jquery unbind()方法 语法
    jquery trigger() 方法 语法
    jquery toggle()方法 语法
    jquery change() 函数 语法
    jquery blur()函数 语法
    jquery bind()方法 语法
    jquery checked选择器 语法
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7209233.html
Copyright © 2011-2022 走看看