题目链接
题解:这个题我们可以用拓扑排序来写。我们可以这么思考,当栈中的个数大于b数组给的要求的时候,那么把这些数弹掉,且弹掉的数中最小的数连向i(因为这个最小的数要比放进去的数大),在这个过程中我们建边,表示该点要比这个点大,然后再执行一遍拓扑排序,注意拓扑排序的时候我们要从大到小进行赋值,因为我们建边的时候是从大指向小的。这个题就可以完成了。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
#define endl "\n"
using namespace std;
const int maxn = 1e6 + 5;
int deg[maxn], to[maxn], sta[maxn];
int b[maxn], v[maxn];
int n, k;
void bfs()
{
queue<int> q;
for (int i = 1; i <= n;i++)
{
if(deg[i]==0) q.push(i);
}
int ans = n;//从大开始赋值
while(q.size())
{
int a = q.front();
q.pop();
v[a] = ans--;
if(--deg[to[a]]==0)
q.push(to[a]);
}
}
int main()
{
cin >> n >> k;
for (int i = 1; i <= k;i++)
{
int x;
cin >> x;
cin >> b[x];
}
int res = 0;
bool flag = 0;
for (int i = 1; i <= n;i++)
{
if(b[i])
{
if(b[i]>res+1)
{
flag = 1;
break;
}
bool g = 0;
while(b[i]<res+1)
{
res--, g = 1;
}
if(g)
to[sta[res + 1]] = i;//表示最小的数要比i位置的数大
}
sta[++res] = i;
to[sta[res]] = sta[res - 1];//指向栈顶
}
if(flag)
{
cout << -1;
return 0;
}
for (int i = 1; i <= n;i++)
{
deg[to[i]]++;
}
bfs();
for (int i = 1; i <= n;i++)
{
printf("%d ", v[i]);
}
}