拓扑排序、bfs"/>
UESTC 1635 琵琶弦上说相思,当时明月在,曾照彩云归 拓扑排序、bfs
琵琶弦上说相思,当时明月在,曾照彩云归
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)Submit Status
给你n个仅由小写字母组成的字符串,请你找出一种字典序,使得这n个字符串在这种字典序下是从小到大排列的.
Input
第一行一个整数n(1≤n≤1000),表示有n个字符串.接下来n行,每行一个字符串,每个字符串的长度不超过200,不含空串.
Output
如果无解,输出−1.如果有解,输出一个长度为26的字符串,其中第ii个字母表示这种字典序下第ii小的字母.
如果有多个解,输出在字典序"abcdefghijklmnopqrstuvwxyz"下最小的那一个.
Sample input and output
Sample Input Sample Output10 aghjlnopefikdmbcqrstuvwxyz
petr
egor
endagorion
feferivan
ilovetanyaromanova
kostka
dmitriyh
maratsnowbear
bredorjaguarturnik
cgyforever
Source
2017 UESTC Training for Graph Theory
UESTC 1635 琵琶弦上说相思,当时明月在,曾照彩云归
My Solution
题意:给出n个仅由小写字母组成的字符串,要求找出一种字典序,
使得这n个字符串在这种字典序下是从小到大排列的。
拓扑排序、bfs
对于相邻的2个字符串当第一次遇到不相等的字符是前一个u必定比比后一个v小,
所以可以u向v连一条有向边。
然后对于建出的这个图,跑一次拓扑排序即可。
时间复杂度 O(n*length)
空间复杂度 O(n*length)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> ii;
const int MAXN = 1e3 + 8;char s[MAXN][208];
vector<int> sons[26];
priority_queue<ii, vector<ii>, greater<ii>> pq;
queue<int> q;
int deg[26];
bool flag[MAXN];
inline void bfs()
{int u, v, fa, sz, i;while(!pq.empty()){u = pq.top().first;fa = pq.top().second;pq.pop();q.push(u);flag[u] = true;sz = sons[u].size();for(i = 0; i < sz; i++){v = sons[u][i];if(v == fa) continue;deg[v]--;if(deg[v] == 0){pq.push(ii(v, u));}}}
}int main()
{#ifdef LOCALfreopen("d.txt", "r", stdin);//freopen("d.out", "w", stdout);int T = 1;while(T--){#endif // LOCAL//ios::sync_with_stdio(false); cin.tie(0);int n, i, j, len1, len2;bool ans = true, f;//cin >> n;scanf("%d", &n);for(i = 0; i < n; i++){scanf("%s", s[i]);}for(i = 0; i < n - 1; i++){len1 = strlen(s[i]);len2 = strlen(s[i+1]);f = false;for(j = 0; j < min(len1, len2); j++){if(s[i][j] != s[i+1][j]){f = true;sons[s[i][j] - 'a'].push_back(s[i+1][j] - 'a');break;}}if(!f){if(len1 > len2){ans = false;break;}}}if(!ans) printf("-1\n");else{int sz;for(i = 0; i < 26; i++){sz = sons[i].size();for(j = 0; j < sz; j++){deg[sons[i][j]]++;}}for(i = 0; i < 26; i++){if(sons[i].size() && deg[i] == 0){pq.push(ii(i, -1));}}bfs();for(i = 0; i < 26; i++){if(deg[i] != 0){ans = false;break;}}if(!ans) printf("-1\n");else{i = 0;while(!q.empty()){while(flag[i]) i++;while(i < q.front()){putchar(char('a' + i));i++;while(flag[i]) i++;}putchar(char('a' + q.front()));q.pop();}while(flag[i]) i++;while(i < 26){putchar(char('a' + i));i++;while(flag[i]) i++;}}}#ifdef LOCALcout << endl;}#endif // LOCALreturn 0;
}
Thank you!
------from ProLights
更多推荐
UESTC 1635 琵琶弦上说相思,当时明月在,曾照彩云归 拓扑排序、bfs
发布评论