NOIP2016(PJT4) 车站分级

挺好的思路的一个题

Description

link

在一个长度为 (n) 的序列上每一个数都有一个优先级,然后我们给出 (m) 条限制

每个限制组中的数的优先级必须大于等于同组数的优先级

问最小的(max)优先级

(n,m leq 1000)

Solution

还是点链接看原题吧,博主的题意概述分别指向了二分和差分约束

然而这个是一个拓扑题

读题读题读题我们发现:在这个路线上(原题中提到了这个概念)没有停靠的点的优先级比数列中任何一个都小

然后建图,跑拓扑序,这题没了

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
	inline int read()
	{
		int res=0,f=1; char k;
		while(!isdigit(k=getchar())) if(k=='-') f=-1;
		while(isdigit(k)) res=res*10+k-'0',k=getchar();
		return res*f;
	}
	const int N=1010;
	struct node{
		int to,nxt;
	}e[N<<9];
	int head[N],num[N],n,m,cnt,st[N][N],in[N],ans,res[N];
	bool fl[N],vis[N][N];
	inline void add(int u,int v)
	{
		e[++cnt].nxt=head[u]; e[cnt].to=v;
		return head[u]=cnt,void();
	}  
	queue<int> q;
	signed main()
	{
		n=read(); m=read();
		for(int i=1;i<=m;++i)
		{
			num[i]=read(); memset(fl,0,sizeof(fl));
			for(int j=1;j<=num[i];++j)
			{
				st[i][j]=read(); fl[st[i][j]]=1;
			}
			for(int j=st[i][1];j<=st[i][num[i]];++j)
			{
				if(fl[j]) continue;
				for(int k=1;k<=num[i];++k)
				{
					if(!vis[j][st[i][k]])
					{
						add(j,st[i][k]); in[st[i][k]]++; vis[j][st[i][k]]=1;
					}
				}
			}
		}	
		for(int i=1;i<=n;++i) if(!in[i]) q.push(i),res[i]=1;
		while(!q.empty())
		{
			int fr=q.front(); q.pop(); ans=max(ans,res[fr]);
			for(int i=head[fr];i;i=e[i].nxt)
			{
				int t=e[i].to; in[t]--;
				if(!in[t]) res[t]=res[fr]+1,q.push(t);
			}
		}
		return cout<<ans<<endl,0;
	}
}
signed main(){return yspm::main();} 
原文地址:https://www.cnblogs.com/yspm/p/12508386.html