很容易想到是根据区间包含关系建图后跑拓扑序,但是为什么正着跑最小字典序是 WA,反着跑最大字典序 AC?
正序:
#include<bits/stdc++.h>
using namespace std;
int n,L[505],R[505],du[505];
vector<int>G[505];
priority_queue<int>Q;
int ans[505];
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>L[i]>>R[i];
du[i]=ans[i]=0;
G[i].clear();
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(L[i]<L[j]&&R[j]<R[i]){
G[j].push_back(i);
du[i]++;
}
}
}
while(Q.size())Q.pop();
for(int i=1;i<=n;i++)if(du[i]==0)Q.push(-i);
int cnt=0;
while(Q.size()){
int u=-Q.top(); Q.pop();
ans[u]=++cnt;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
du[v]--;
if(du[v]==0)Q.push(-v);
}
}
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
cout<<endl;
}
signed main(){
int T;cin>>T;
while(T--)solve();
}

倒序:
#include<bits/stdc++.h>
using namespace std;
int n,L[505],R[505],du[505];
vector<int>G[505];
priority_queue<int>Q;
int ans[505],p[505];
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>L[i]>>R[i];
du[i]=ans[i]=0;
G[i].clear();
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(L[i]<L[j]&&R[j]<R[i]){
G[i].push_back(j);
du[j]++;
}
}
}
while(Q.size())Q.pop();
for(int i=1;i<=n;i++)if(du[i]==0)Q.push(i);
int cnt=0;
while(Q.size()){
int u=Q.top();Q.pop();
ans[++cnt]=u;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
du[v]--;
if(du[v]==0)Q.push(v);
}
}
reverse(ans+1,ans+n+1);
for(int i=1;i<=n;i++)p[ans[i]]=i;
for(int i=1;i<=n;i++)cout<<p[i]<<" ";
cout<<endl;
}
signed main(){
int T;cin>>T;
while(T--)solve();
}
