车站分级

这是一道拓补排序的题,我们的目的是找最少有几级的车站,可以转化为建图然后找图一共有几层;

把每次组数据都视为一层,把每一层没有停下的车站做一条单向边连到停下的车站上,那么每一条路便代表了一层,最后在根据拓补排序的算法看一共要跑几次。

#include<cstdio>
	#include<iostream>
	#include<algorithm>
	#include<cstring>
	#include<queue>
	using namespace std;
	int sta[1010],map[1010][1010],in[1010];
	bool vis[1010];
	int main(){
		int t,n,m;
		queue<int>q;
		cin>>n>>m; 
		for(int i=1;i<=m;i++){
			memset(vis,0,sizeof(vis));
			cin>>t;
			for(int j=1;j<=t;j++){
				cin>>sta[j];
				vis[sta[j]]=true;
			}
			for(int j=sta[1];j<sta[t];j++){
				if(!vis[j]){
					vis[j]=true;
					for(int k=1;k<=t;k++){
						if(map[j][sta[k]]==0){//把没有停下的车站连接到停下的
							map[j][sta[k]]=1;
							in[sta[k]]++;
						}
					}
				}
			}	
		}
		memset(vis,0,sizeof(vis));
		int ans=0;
		while(1){//只要还有数就一直循环
			for(int i=1;i<=n;i++){
				if(in[i]==0&&!vis[i]){
					q.push(i);
					vis[i]=true;
				}
			}
			if(q.empty())break;//一旦都找完了,就跳出
			while(!q.empty()){	
				for(int i=1;i<=n;i++){
					if(map[q.front()][i]==1){
						map[q.front()][i]=0;
						in[i]--;	
					}
				}
				q.pop();//每找完一个就把找的弹出来
			}
			ans++;
		}	
		cout<<ans;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值