题意
上了大学后,小S迎来了自己的第一次数分考试。一共有nn个人参加了考试。
无聊的助教决定不告诉大家每个人的名次,而是让大家自己猜。
首先,大家知道了第ii个人的名次区间是[Li,Ri][Li,Ri]。
除此之外,又有mm条其他信息,形如ui,viui,vi,表示第uiui个人考的要比vivi好(即排名更低)。
现在,小S想要知道,是否有一个合法的排名,满足上述所有的要求。如果有,请输出任意一组解,否则输出"-1"(不含括号)。
输入格式
第一行两个整数 n,mn,m,表示人数和限制条数。
接下来nn行,每行两个正整数Li,RiLi,Ri。
接下来mm行,每行两个正整数ui,viui,vi。
输入格式
如果无解输出-1。
否则输出nn行,每行11个整数,其中第ii个表示第ii名的id。编号从1开始。
样例1
input
3 3
1 3
1 3
1 3
1 2
2 3
3 1
output
-1
样例2
input
3 3
1 3
1 3
1 3
1 2
2 3
1 3
output
1
2
3
限制与约定
对于 10%10% 的数据,满足 n,m≤10n,m≤10。
对于 30%30% 的数据,满足 n,m≤100n,m≤100。
对于 60%60% 的数据,满足 n≤105,m≤105n≤105,m≤105。
对于 100%100% 的数据,满足 n≤3×105,m≤106n≤3×105,m≤106。
时间限制:2 s
空间限制:512 MB
故事的后续
小S虽然考了97,但是他惊喜地发现全班的前25%25%是96分。
思路??
- 考虑topsort,但topsort每个位置必定不唯一,那么我们就把i的topsort尽量移动到给定的【li,ri】里。
- 假如我们的topsort已经考虑到第x位,那么任意li<x的i都可以成为本个位置的元素,我们优先把r小的放在此位置
- 用两个priority_queue维护一下
code ?? 10分
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstdlib>
#include<ctime>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
inline int read(){
char ch=' ';int f=1;int x=0;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int N=3e5+100;
const int M=1e6+100;
int l[N],r[N];
struct node
{
int v,nxt;
int w;
}edge[M];
int head[N],cnt;
void add(int u,int v)
{
cnt++;
edge[cnt].v=v;
edge[cnt].nxt=head[u];
head[u]=cnt;
}
int in[N];
int topsort[N];
priority_queue <pair<int,int> > q;
priority_queue <pair<int,int> > qr;
int main()
{
int n,m;
n=read();m=read();
int i,j;
for(i=1;i<=n;i++)
{
l[i]=read();
r[i]=read();
}
for(i=1;i<=m;i++)
{
int u,v;
u=read();v=read();
add(u,v);
in[v]++;
}
for(i=1;i<=n;i++)
{
if(in[i]==0)
{
q.push(make_pair(l[i],i));
}
}
int cnt=1;
int x;
for(i=1;i<=n;i++)
{
if(!q.empty()) x=q.top().second;
else
{
cout<<"-1"<<endl;
return 0;
}
while(l[x]<=cnt)
{
q.pop();
qr.push(make_pair(r[x],x));
if(!q.empty())
{
x=q.top().second;
}
else
{
break;
}
}
if(!qr.empty())
{
x=qr.top().second;
qr.pop();
}
else
{
cout<<"-1"<<endl;
return 0;
}
if(r[x]>=cnt)
{
topsort[cnt]=x;cnt++;
for(j=head[x];j;j=edge[j].nxt)
{
int v=edge[j].v;
in[v]--;
if(in[v]==0)
{
q.push(make_pair(l[v],v));
}
}
}
else
{
cout<<"-1"<<endl;
return 0;
}
}
for(i=1;i<=n;i++)
{
cout<<topsort[i]<<endl;
}
return 0;
}
zj
https://www.cnblogs.com/yzxverygood/p/9887165.html
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
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;
}