牛客第五場 H subsequence 2 —— 拓撲排序

題目鏈接:點我啊╭(╯^╰)╮

題目大意:

    長度爲 nn 的字符串,以及 m(m1)/2m⋅(m−1)/2 次說明
    每次說明給出兩個字符,然後告訴這所有兩個字符在原串中的相對位置
    最後還原該串

解題思路:

    易得,若有答案,只能爲一種
    給出兩個字符的所有位置,即可將任意兩個字符的關係表示出來
    建完圖後,拓撲排序的結果即爲答案

核心:拓撲排序在串中的運用

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const int maxn = 1e4 + 5;
int n, m, in[26][maxn];
int cnt[26], num[26];
char s[maxn], two[2];
vector <pii> G[26][maxn];
vector <char> ans;

void tp_sort(){
	queue <pii> Q;
	for(int i=0; i<26; i++)
		if(num[i] && in[i][0]==0)
			Q.push({i, 0});
	while(!Q.empty()){
		pii q = Q.front();
		Q.pop();
		ans.push_back(char(q.first + 'a'));
		for(auto i : G[q.first][q.second]){
			in[i.first][i.second]--;
			if(in[i.first][i.second]==0)
				Q.push(i);
		}
	}
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i=0; i<m*(m-1)/2; i++){
		int len, t0, t1;
		scanf("%s%d", two, &len);
		if(!len) continue;
		scanf("%s", s);
		memset(cnt, 0, sizeof(cnt));
		for(int j=0; j<len; j++){
			if(j){
				t1 = s[j] - 'a';
				G[t0][cnt[t0]-1].push_back({t1, cnt[t1]});
				in[t1][cnt[t1]]++;
				t0 = t1, cnt[t1]++;
			}
			else t0 = s[j] - 'a', cnt[t0]++;
		}
		num[two[0]-'a'] = cnt[two[0]-'a'];
		num[two[1]-'a'] = cnt[two[1]-'a'];
	}
	
	tp_sort();
	if(ans.size() != n) puts("-1");
	else for(auto i : ans) printf("%c", i);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章