拓扑排序 不会
那我们可以尝试将指出来的车站与未指出来的车站连边,跑最长路就行了。。。
如果用邻接矩阵的话,是不需要判重的,注意更新数据,跑spfa即可,最后答案应当加上1因为有单独的一级。但会TLE, 只能得70分。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
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<<s<<' '<<t<<endl;
int now=team[s];
//cout<<now<<' '<<dis[now]<<' '<<endl;
s++;
s%=n;
f[now]=false;
for(int i=1;i<=n;i++)
{
if(a[now][i]!=0&&dis[i]<dis[now]+a[now][i])
{
// cout<<now<<' '<<i<<' '<<dis[now]<<' '<<dis[i]<<endl;
dis[i]=dis[now]+a[now][i];
if(f[i]==false)
{
team[t]=i;
t++;
t%=n;
f[i]=true;
}
}
}
}
for(int i=1;i<=n;i++)
{
way=max(way,dis[i]);
}
return way;
}
int main()
{
//freopen("data.txt","r",stdin);
cin>>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<<ans+1<<endl;
return 0;
}
那我们需要考虑邻接表,虽然这样能节省空间,但就增加了一个新的判断是否重复建边的问题。判断之后,内存还是会占很多(n*n*m)这个时候,我们就需要设一个虚点(n++),将标记的车站与未标记的车站通过虚点相连,这样就变成(2*n)了,方便许多。注意空间要开的足够大
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
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<<endl;
return 0;
}