noip 模拟 #17T1 search

诶呦

我就傻了

我们对于每个点其实最多只用连两条边就可以了

而拓扑排序是O(M)的

所以我们就直接瞎搞啦

然而我刚开始想不出来怎么瞎搞QAQ

就很菜

#include<cstdio>
#include<cstring>
inline int read()
{
	int ans=0;char t=getchar();
	while(t<'0'||t>'9')	t=getchar();
	while(t>='0'&&t<='9')	ans=ans*10+t-'0',t=getchar();
	return ans;
}
const int N=1e5+27;
struct node
{
	int to,next;
}e[2*N];
int first[N];
int cnt;
int cd[N];
void insert(int u,int v)
{
	e[++cnt]=(node){v,first[u]};first[u]=cnt;
	cd[v]++;
}
int qu[N+7];
int a[N],ans[N];
int ls[N];
int main()
{
	freopen("search.in","r",stdin);
	freopen("search.out","w",stdout);
	int time=read();
	while(time--)
	{		
		memset(first,0,sizeof(first));
		memset(cd,0,sizeof(cd));
		memset(ls,0,sizeof(ls));
		int n=read();
		for(int i=1;i<=n;i++)	a[i]=read();
		cnt=0;
		bool tag=1;
		for(int i=1;i<=n&&tag;i++)
		{
			if(ls[a[i]-1])	insert(i,ls[a[i]-1]);
			else if(a[i]!=1)		printf("No\n"),tag=0;
			if(ls[a[i]])		insert(ls[a[i]],i);
			ls[a[i]]=i;
		}
		if(!tag)	continue;
		int head=1,tail=2;
		cnt=n;
		for(int i=1;i<=n;i++)	if(!cd[i])	qu[tail++]=i,ans[i]=cnt--;
		while(head!=tail)
		{
			int rr=qu[head++];if(head==N)	head=0;
			for(int k=first[rr];k;k=e[k].next)
			if(!--cd[e[k].to]){
				ans[e[k].to]=cnt--;qu[tail++]=e[k].to;if(tail==N)tail=0;
			}
		}
		for(int i=1;i<=n;i++)	printf("%d ",ans[i]);
		printf("\n");
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值