P6286 [COCI2016-2017#1] Cezar
阿新 • • 發佈:2022-04-01
這個題好難 真的好難
對拓撲排序不是很熟練 但是能明顯感覺到強烈的先後順序 但是就是建不了邊
因為這個題要求最後的目標順序 那我們就按照他的目標順序進行插入字典樹
這樣的好處就是 已經在字典樹裡面同層的點一定是要在現在插入點前面出現的
字首這個點太容易忽略了 不過題目還算良心 只有兩個點有字首 要是每個點都有字首 那真的就暴斃了
點選檢視程式碼
#include<bits/stdc++.h> using namespace std; #define lowbit(x) x&(-x) #define ll long long const int maxn=1e5+5; bool pd=true; int tr[maxn][26]; int n,cnt,tt; int num[maxn],inn[maxn],ans[maxn]; vector<int>Q[maxn]; void insert(string ss); string s[105]; queue<int>q; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>s[i]; for(int i=1;i<=n;i++)cin>>num[i],insert(s[num[i]]); if(!pd){ cout<<"NE"<<endl; return 0; } for(int i=0;i<26;i++) if(!inn[i])q.push(i);// while(!q.empty()){ int u=q.front();q.pop(); if(ans[u]){ cout<<"NE"<<endl; return 0; } ans[u]=++tt; for(int i=0;i<Q[u].size();i++){ int to=Q[u][i]; inn[to]--; if(!inn[to]) q.push(to); } } for(int i=0;i<26;i++) if(inn[i]){ cout<<"NE"<<endl; return 0; } cout<<"DA"<<endl; char c; for(int i=0;i<26;i++){ if(!ans[i])ans[i]=++tt; c=ans[i]-1+'a'; cout<<c; } cout<<endl; return 0; } void insert(string ss){ int root=0; for(int i=0;i<ss.size();i++){ int id=ss[i]-'a'; if(!tr[root][id])tr[root][id]=++cnt; for(int i=0;i<26;i++) if(i!=id&&tr[root][i])Q[i].push_back(id),inn[id]++; root=tr[root][id]; } for(int i=0;i<26;i++) if(tr[root][i]){ pd=false; return ; } }