zoukankan      html  css  js  c++  java
  • POJ 2337 Catenyms(欧拉回(通)路:路径输出+最小字典序)

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

    题目大意:给你n个字符串,只有字符串首和尾相同才能连接起来。请你以最小字典序输出连接好的单词。

    解题思路:跟POJ1386一个意思,就是把26个字母当成点,单词当做有向边,判断欧拉回(通)路。但是要输出路径也就是单词,而且要求字典序最小。

    可以通过将单词先排序再添加边使字典序最小,还有注意起点,如果有一个出度比入度大1的点,就从这个点出发,否则从最小的点出发。

    代码:

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<string>
      6 #include<stack>
      7 #define CLR(arr,val) memset(arr,val,sizeof(arr))
      8 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
      9 using namespace std;
     10 const int M=2e4+5;
     11 const int N=1e4+5;
     12 
     13 struct node{
     14     int to,next;
     15     string w;
     16 }edge[M];
     17 
     18 int idx;
     19 int indeg[N],outdeg[N],head[N];
     20 string str[M];
     21 bool vis[M];
     22 stack<string>sk;
     23 
     24 void init(){
     25     idx=1;
     26     CLR(head,0);
     27     CLR(indeg,0);
     28     CLR(outdeg,0);
     29     CLR(vis,false);
     30     while(!sk.empty()){
     31         sk.pop();
     32     }
     33 }
     34 
     35 void addedge(int u,int v,string w){
     36     edge[idx].to=v;
     37     edge[idx].w=w;
     38     edge[idx].next=head[u];
     39     head[u]=idx++;
     40 }
     41 
     42 void dfs(int u){
     43     for(int &j=head[u];j;j=edge[j].next){
     44         node t=edge[j];
     45         if(!vis[j]){
     46             vis[j]=true;
     47             dfs(t.to);
     48             sk.push(t.w);
     49         }
     50     }
     51 }
     52 
     53 int main(){
     54     FAST_IO;
     55     int t;
     56     cin>>t;
     57     while(t--){
     58         init();
     59         int n;
     60         cin>>n;
     61         for(int i=0;i<n;i++)
     62             cin>>str[i];
     63         sort(str,str+n);
     64         int start=100;
     65         //字典序大的先加入,因为静态邻接表是反向添加的 
     66         for(int i=n-1;i>=0;i--){
     67             int u,v;
     68             u=str[i][0]-'a';
     69             v=str[i][str[i].length()-1]-'a';
     70             outdeg[u]++;
     71             indeg[v]++;
     72             addedge(u,v,str[i]);
     73             start=min(start,min(u,v));
     74         }
     75         int chu=0,ru=0;
     76         bool flag=true;
     77         for(int i=0;i<26;i++){
     78             if(indeg[i]+outdeg[i]==0)
     79                 continue;
     80             if(indeg[i]!=outdeg[i]){
     81                 if(indeg[i]+1==outdeg[i]){
     82                     chu++;
     83                     start=i;                //如果有一个出度比入度大1的点,就从这个点出发,否则从最小的点出发
     84                 }
     85                 else if(indeg[i]-1==outdeg[i])
     86                     ru++;
     87                 else
     88                     flag=false;
     89             }
     90         }
     91         if(flag&&(chu==1&&ru==1||chu==0&&ru==0)){
     92             dfs(start);
     93             if(sk.size()==n){
     94                 while(!sk.empty()){
     95                     if(sk.size()==1)
     96                         cout<<sk.top()<<endl;
     97                     else
     98                         cout<<sk.top()<<".";
     99                     sk.pop();
    100                 }
    101             }
    102             else
    103                 puts("***");
    104         }
    105         else
    106             puts("***");
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    html5 canvas雨点打到窗玻璃动画
    html5跟随鼠标炫酷网站引导页动画特效
    如何实现复选框的全选和取消全选效果
    CSS3透明属性opacity
    jQuery实现方式不一样的跳转到底部
    ul li设置横排,并除去li前的圆点
    jQuery美女幻灯相册轮播源代码
    微软modern.IE网站,多版本IE免费测试工具集
    css中position与z-index
    C#一个方法返回多个值
  • 原文地址:https://www.cnblogs.com/fu3638/p/7933269.html
Copyright © 2011-2022 走看看