【题解】洛谷P1983 车站分级

拓扑排序 不会

那我们可以尝试将指出来的车站与未指出来的车站连边,跑最长路就行了。。。

如果用邻接矩阵的话,是不需要判重的,注意更新数据,跑spfa即可,最后答案应当加上1因为有单独的一级。但会TLE, 只能得70分。

#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1010;
const int maxm=100020;
int a[maxn][maxn];
bool b[maxn][maxn];
int n,m;
int cnt[maxn];
bool q[maxn];
bool f[maxn];
int team[maxn,dis[maxn];
int s=0,t=0;
int ans=-1e9;
int spfa(int x)
{
	int way=-1e9;
	memset(team,0,sizeof(team));
	memset(f,false,sizeof(f));
	memset(dis,0,sizeof(dis));
	s=0,t=0;
	team[t]=x;
	t++;
	f[x]=true;
	while(s!=t)
	{
		//cout<>n>>m;
	memset(a,0,sizeof(a));
	for(int i=1;i<=m;i++)
	{
		memset(q,false,sizeof(q));
		int x;
		int w1=0,w2=0; 
		cin>>x;
		for(int qq=1;qq<=x;qq++)
		{
			int w;
			cin>>w;
			if(qq==1) w1=w;
			if(qq==x) w2=w;
			q[w]=true;
		}
		for(int qq=w1;qq<=w2;qq++)
		{
			for(int j=w1;j<=w2;j++)
			{
				if(q[qq]==true&&q[j]==false)
				{
					a[qq][j]=1;
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		ans=max(ans,spfa(i));
	}
	cout<

那我们需要考虑邻接表,虽然这样能节省空间,但就增加了一个新的判断是否重复建边的问题。判断之后,内存还是会占很多(n*n*m)这个时候,我们就需要设一个虚点(n++),将标记的车站与未标记的车站通过虚点相连,这样就变成(2*n)了,方便许多。注意空间要开的足够大

#include
#include
#include
#include
#include
using namespace std;
const int maxn=1010;
const int maxm=2100000;
int dis[maxm],a[maxn];
bool b[maxn];
int n,m;
int tot,head[maxn*2],nnext[maxm],to[maxm];
void add(int x,int y)
{
	tot++;
	nnext[tot]=head[x];
	head[x]=tot;
	to[tot]=y;
}
int f(int x)
{
	if(dis[x]!=0) return dis[x];
	for(int i=head[x];i;i=nnext[i])
	{
		dis[x]=max(dis[x],f(to[i]));
	}
	dis[x]++;
	return dis[x];
}
int main()
{
	scanf("%d%d",&n,&m);
	int l=n;
	for(int i=1;i<=m;i++)
	{
		int x;
		cin>>x;
		memset(b,false,sizeof(b));
		for(int j=1;j<=x;j++)
		{
			cin>>a[j];
			b[a[j]]=true;
		}
		l++;
		for(int j=a[1];j<=a[x];j++)
		{
			if(b[j]) add(l,j);
		}
		for(int p=a[1];p<=a[x];p++)
		{
			if(!b[p]) add(p,l);
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		ans=max(ans,f(i));
	 } 
	 cout<<(ans+1)/2<

 

你可能感兴趣的:(题解,最短路)