我们就是要对⼀个DAG求⼀个拓扑序,使得第i个的顺序在(li,ri)中。
⾸先,我们先把这个ri的限制收紧,让它变成⼀个真的限制考虑我们平时求⼀个拓扑序都是⽤⼀个队列维护,我们现在为了满⾜ri的限制,我们⽤⼀个优先队列维护这个队列。
假设现在要求字典序的第r个东⻄,那么可以把所有已经被扩展过的且li=t的加⼊单调队列。
接着,从单调队列⾥选出ri最⼩的⼀个点来扩展,把它作为字典序的第t个。
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
int n,m,le[300100],ri[300100],T,d[300100],id[300100],vis[300100],now[300100];
vector<int>v[300100];
priority_queue<pair<int,int> >ql,qr;
inline void dfs(int x)
{
if(now[x])
{
puts("-1");
exit(0);
}
else if(vis[x])
return;
now[x]=1;
for(int i=0;i<v[x].size();i++)
{
dfs(v[x][i]);
ri[x]=min(ri[x],ri[v[x][i]]-1);
}
vis[x]=1;
now[x]=0;
}
int main(){
int i,j,k;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d%d",&le[i],&ri[i]);
for(i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
v[x].pb(y);
d[y]++;
ri[x]=min(ri[x],ri[y]);
}
for(i=1;i<=n;i++)
if(!d[i]&&!vis[i])
dfs(i);
for(i=1;i<=n;i++)
if(!d[i])
ql.push(mp(-le[i],i));
T=1;
while(!ql.empty()&&-ql.top().fi<=T)
qr.push(mp(-ri[ql.top().se],ql.top().se)),ql.pop();
while(!qr.empty())
{
int x=qr.top().se;qr.pop();
if(ri[x]<T)
{
puts("-1");
return 0;
}
id[T]=x;T++;
for(i=0;i<v[x].size();i++)
{
if(d[v[x][i]])
{
d[v[x][i]]--;
if(!d[v[x][i]])
ql.push(mp(-le[v[x][i]],v[x][i]));
}
}
while(!ql.empty()&&-ql.top().fi<=T)
qr.push(mp(-ri[ql.top().se],ql.top().se)),ql.pop();
}
for(i=1;i<=n;i++)
{
if(!id[i])
{
puts("-1");
return 0;
}
}
for(i=1;i<=n;i++)
printf("%d\n",id[i]);
return 0;
}