P1983 车站分级(拓扑排序)

车站分级

题目传送门

解题思路

这题就是用拓扑排序分层
首先是建图
每进行一次输入,就将没有停靠的站与停靠的站都建立一条边
因为题目样例不怎么大,所以可以用邻接矩阵

for(int i=1;i<=m;i++)//输入
{
	cin>>x;
	memset(c,0,sizeof(c));//清零
	for(int j=1;j<=x;j++)
	{
		cin>>a[j];
		c[a[j]]=1;//标记
	}
	for(int j=a[1];j<=a[x];j++)//建图
	 if(c[j]==0)//不是停靠站
	  for(int k=1;k<=x;k++)
	   if(map[j][a[k]]==0)//如果无边
	   {
		 du[a[k]]++;//入度++
		 map[j][a[k]]=1;//建边
	   }
}

拓扑中,用一个f存层数,用一个s找最大层数

f[i]=f[p[h]]+1;//dp
s=max(s,f[i]);//找最大

呈上AC代码

AC代码

#include
#include
using namespace std;
int n,m,x,h,t,s,a[1005],c[1005],p[1005],f[1005],du[1005],map[1005][1005];
void tp()
{
	memset(c,0,sizeof(c));
	for(int i=1;i<=n;i++)//找度为0的入队
	 if(du[i]==0){p[++t]=i;c[i]=1;f[i]=1;}//入队,标记,初值
	while(h<t)
	{
		h++;
		for(int i=1;i<=n;i++)//枚举点
		 if(map[p[h]][i]==1&&c[i]==0)//如果有边并且没有标记
		 {
		 	du[i]--;//度--(删边)
		 	if(du[i]==0)//如果度为0
		 	{
		 		f[i]=f[p[h]]+1;//dp
		 		s=max(s,f[i]);//找最大
		 		c[i]=1;//标记
		 		p[++t]=i;//入队
		 	}
		 }
	} 
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)//输入
	{
		cin>>x;
		memset(c,0,sizeof(c));//清零
		for(int j=1;j<=x;j++)
		{
			cin>>a[j];
			c[a[j]]=1;//标记
		}
		for(int j=a[1];j<=a[x];j++)//建图
	 	 if(c[j]==0)//不是停靠站
	  	  for(int k=1;k<=x;k++)
	   	   if(map[j][a[k]]==0)//如果无边
	   	   {
		 	du[a[k]]++;//入度++
		 	map[j][a[k]]=1;//建边
	   	   }
	}
	tp();//拓扑
	cout<<s;//输出
}

谢谢

你可能感兴趣的:(拓扑排序,动规dp)