[NOIP2013普及组]车站分级

题目:洛谷P1983、Vijos P1851、codevs3294。

题目大意:有一些车停靠某些站。现在要给所有站分级,规定一辆车停靠的所有站的最小级数必须大于(起点-终点)所有不停靠的站的最大级数。问至少分成几种不同的级数?

解题思路:由于停靠的站级数大于不停靠的站,我们把每列车停靠的站向不停靠的连一条有向边。

然后对其进行拓扑排序,拓扑序列的最大值就是答案。

注意在连边时先枚举不停靠的站,因为如果它停靠了就可以直接跳过循环,避免不必要的操作(反过来就TLE了)。

C++ Code:

#include<cstdio>
#include<cstring>
#include<cctype>
bool b[1011][1011],use[1011];
int n,m,d[1011],a[1011],ceng[1011],q[123457];
inline int readint(){
	char c=getchar();
	for(;!isdigit(c);c=getchar());
	int p=0;
	for(;isdigit(c);c=getchar())p=(p<<3)+(p<<1)+(c^'0');
	return p;
}
int main(){
	memset(d,0,sizeof d);
	memset(b,0,sizeof b);
	m=readint();
	n=readint();
	for(int i=1;i<=n;++i){
		memset(use,0,sizeof use);
		int num=readint();
		for(int j=1;j<=num;++j)
		use[a[j]=readint()]=true;
		for(int k=a[1];k<=a[num];++k)
		if(!use[k]){
			for(int j=1;j<=num;++j)
			if(!b[a[j]][k]){
				b[a[j]][k]=true;
				++d[k];
			}
		}
	}
	int l=0,r=0,ans=1;
	memset(ceng,0,sizeof ceng);
	for(int i=1;i<=m;++i)
	if(!d[i])ceng[q[++r]=i]=1;
	while(l!=r){
		int u=q[++l];
		for(int i=1;i<=m;++i)
		if(b[u][i]&&!--d[i]){
			ans=ceng[q[++r]=i]=ceng[u]+1;
		}
	}
	printf("%d\n",ans);
	return 0;
}

 

转载于:https://www.cnblogs.com/Mrsrz/p/7683298.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值