codeforces 510C Fox And Names 拓撲

題意:n個姓名,按照某種“字典序”。

問如果存在這樣的字典序,輸出字典序'a'到‘z’26個字母的順序。

思路:拓撲排序。對於str[i]和str[i+1]如果在位置k出現不同,那麼x=str[i][k]-'a'+1,y=str[i+1][k]-'a'+1,從x->y連一條邊,y的入度in[y]++。

然後拓撲排序,如果形成環,就說明不行,不然依次輸出對應字符。(ps:len1爲str[i]的長度,len2爲str[i+1]的長度,如果len1>len2且前len2個均相同,也說明不行)詳見代碼:

/*********************************************************
  file name: codeforces510C.cpp
  author : kereo
  create time:  2015年02月03日 星期二 16時03分28秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=100+50;
const int MAXN=100000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=100000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int n,edge_cnt;
char str[N][N];
int head[N],in[N],ans[N],vis[N][N];
struct Edge{
    int v,next;
}edge[N];
void init(){
    edge_cnt=0;
    memset(in,0,sizeof(in));
    memset(vis,0,sizeof(vis));
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v){
    edge[edge_cnt].v=v;
    edge[edge_cnt].next=head[u]; head[u]=edge_cnt++;
}
int main(){
    while(~scanf("%d",&n)){
        init();
        for(int i=0;i<n;i++)
            scanf("%s",str[i]);
        int flag=1;
        for(int i=0;i<n-1;i++){
            int len1=strlen(str[i]),len2=strlen(str[i+1]);
            int tag=0;
            for(int j=0;j<len1 && j<len2;j++){
                if(str[i][j]!=str[i+1][j]){
                    tag=1; 
                    int u=str[i][j]-'a'+1,v=str[i+1][j]-'a'+1;
                    if(!vis[u][v]){
                        vis[u][v]=1; in[v]++; addedge(u,v);
                    }
                    break;
                }
            }
            if(!tag && len1>len2){
                flag=0;
                break;
            }
        }
        if(!flag){
            printf("Impossible\n");
            continue;
        }
        int cnt=0;
        queue<int>Q;
        while(!Q.empty()){
            Q.pop();
        }
        for(int i=1;i<=sigma_size;i++)
            if(!in[i])
                Q.push(i);
        while(!Q.empty()){
            int u=Q.front(); Q.pop();
            ans[cnt++]=u-1;
            for(int i=head[u];i!=-1;i=edge[i].next){
                int v=edge[i].v;
                --in[v];
                if(!in[v])
                    Q.push(v);
            }
        }
        if(cnt != sigma_size)
            printf("Impossible\n");
        else{
            for(int i=0;i<sigma_size;i++)
                printf("%c",'a'+ans[i]);
            printf("\n");
        }
    }
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章