车站分级


题解:

这道题一开始以为是动态规划,但正解是拓扑排序,然后某人说很容易就能想到
拓扑排序,我也不知道是怎么想到的(误)。根据题意我们知道,没有停靠的车站
等级一定比停靠过的车站等级小。因此我们把没有停靠过的车站连一条有向边到
停靠过的车站。可以想象为没有停靠过的从下面向上指向停靠过的,意为等级比

上面的低。 那么每有一层就代表有一个等级,不断地断掉边,每断掉一层就Ans加一

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<cctype>
#include<cmath>
#include<map>
#include<climits>
#include<stack>
#define MAXA 1005
#define MIN -1500000000
using namespace std;
typedef long long LL;
int n,m,Ans,Station[MAXA],s,Con[MAXA][MAXA],degree[MAXA],topo[MAXA],top;
bool isStop[MAXA],isVis[MAXA];
int main() {
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++) {
		memset(isStop,0,sizeof(isStop));
		scanf("%d",&s);
		for(int j=1;j<=s;j++) {
			scanf("%d",&Station[j]);
			isStop[Station[j]] = true;
		}
		for(int j=Station[1];j<=Station[s];j++) {
			if(!isStop[j]) {
				for(int k=1;k<=s;k++)
				    if(!Con[j][Station[k]]) {
				    	Con[j][Station[k]] = 1;
				    	degree[Station[k]]++;
					}
			}
		}
	}
	do {
		top = 0;
		for(int i=1;i<=n;i++)
		    if(degree[i] == 0 && !isVis[i]) {
		    	topo[++top] = i;
		    	isVis[i] = true;
			}
		for(int i=1;i<=top;i++)
		    for(int j=1;j<=n;j++)
		        if(Con[topo[i]][j]) {
		        	Con[topo[i]][j] = 0;
		        	degree[j]--;
				}
		Ans++;
	}while(top);
	printf("%d",--Ans);
}

猜你喜欢

转载自blog.csdn.net/qq_41513352/article/details/79690614