1. 程式人生 > 其它 >CF510c Fox And Names

CF510c Fox And Names

簡單地說,就是給出一張名字的列表,要找到一張字母表使得這張人名的列表是按字典序排列的。

這不就是今年天梯賽的原題嘛?

拓撲排序沒的說

需要注意的點:可能存在字首相等但是長度不等 判斷possible或者impossible的時候這種情況非常容易忽略

再就是如果拓撲排序存在環 也就是最後仍然存在度數不為0的點

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=105;
int n,cnt,tot;
map<char,int>mp;
map<int,char>rk;
vector<int>Q[maxn];
queue<int>QQ;
int du[maxn];
bool flag;
char ans[maxn];
string s[maxn];
void add(int u,int v){
	Q[u].push_back(v);
	du[v]++;
}
void calc(string,string);
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>s[i];
	for(int i=2;i<=n;i++)
	calc(s[i-1],s[i]);
	for(int i=1;i<=cnt;i++)
	if(!du[i])QQ.push(i);
	while(!QQ.empty()){
		int u=QQ.front();
		QQ.pop();ans[++tot]=rk[u];
		for(int i=0;i<Q[u].size();i++){
			int to=Q[u][i];
			du[to]--;
			if(!du[to])QQ.push(to);
		}
	}
	if(tot!=cnt||flag)cout<<"Impossible";
	else {
		for(char i='a';i<='z';i++)
		if(!mp.count(i))
		ans[++tot]=i;
		for(int i=1;i<=tot;i++)cout<<ans[i];
	}
     return 0;
}
void calc(string a,string b){
	int len=min(a.size(),b.size());
	bool cmp=1;
	for(int i=0;i<len;i++){
		if(a[i]!=b[i]){
			if(!mp.count(a[i]))mp[a[i]]=++cnt,rk[cnt]=a[i];
			if(!mp.count(b[i]))mp[b[i]]=++cnt,rk[cnt]=b[i];
			add(mp[a[i]],mp[b[i]]);
			cmp=0;
			break;
		}
	}
	if(cmp==1&&a.size()>b.size())flag=1;
}