CF510c Fox And Names
阿新 • • 發佈:2022-05-17
簡單地說,就是給出一張名字的列表,要找到一張字母表使得這張人名的列表是按字典序排列的。
這不就是今年天梯賽的原題嘛?
拓撲排序沒的說
需要注意的點:可能存在字首相等但是長度不等 判斷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; }