zoukankan      html  css  js  c++  java
  • [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
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    docker生产——容器通信
    .net core集成JWT(基础)
    JWT基本概念
    MySQL数据更新
    MySQL查询练习2
    C语言程序设计之字符串处理
    MySQL查询练习
    博客文章搬迁
    C语言程序设计之 数组2020-10-28
    Java方法重载浅谈
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7683298.html
Copyright © 2011-2022 走看看