拓扑排序——Codeforces Round #290 (Div. 2) C. Fox And Names

    xiaoxiao2021-03-25  55

    题目链接:http://codeforces.com/contest/510/problem/C

    题意:见链接

    分析:对于给出的N个字符串,我们按顺序判断相邻2个字符串,如果前者比后者长,肯定不构成字典序。否则按第一对不相等的字符建有向边。构图结束后,跑一遍拓扑排序,如果得到的字符数最后得到字符数小于26则不构成字典序。

    AC代码:

    /************************************************************************* > File Name: test.cpp > Author: Akira > Mail: qaq.febr2.qaq@gmail.com ************************************************************************/ #include<bits/stdc++.h> typedef long long LL; typedef unsigned long long ULL; typedef long double LD; #define MST(a,b) memset(a,b,sizeof(a)) #define CLR(a) MST(a,0) #define Sqr(a) ((a)*(a)) using namespace std; #define MaxN 200 #define MaxM 1000 #define INF 0x3f3f3f3f #define PI 3.1415926535897932384626 const int mod = 1E9+7; const double eps = 1e-6; #define bug cout<<88888888<<endl; #define debug(x) cout << #x" = " << x << endl; int n; char str[MaxN][110]; struct Edge { int u,v,next; }edge[MaxM]; int cont,head[MaxN]; void add(char u, char v) { edge[cont].u = u; edge[cont].v = v; edge[cont].next = head[u]; head[u] = cont++; } int index[MaxN]; void init() { cont = 0; MST(head,-1); } bool judge() { for(int i=0;i<n-1;i++) { for(int j=1;j<=strlen(str[i]+1);j++) { if( str[i][j]!=str[i+1][j]) { if(str[i][j]==0) return false; add(str[i][j], str[i+1][j]); index[str[i+1][j]]++; break; } } } return true; } char ans[26]; bool topo() { int cnt = 0; for(int i='a';i<='z';i++) if(index[i]==0) ans[cnt++] = i; int h = 0; while(h<cnt) { int now = ans[h++]; for(int i=head[now];i!=-1;i=edge[i].next) { int v = edge[i].v; index[v]--; if(index[v]==0)ans[cnt++] = v; } } if(cnt<26) return false; printf("%s\n", ans); return true; } int main() { init(); //std::ios::sync_with_stdio(false); scanf("%d", &n); for(int i=0;i<n;i++) scanf("%s", str[i]+1); if( judge() && topo()); else printf("Impossible\n"); //system("pause"); }
    转载请注明原文地址: https://ju.6miu.com/read-32175.html

    最新回复(0)