传送门:https://www.luogu.org/problemnew/show/P1983
忘记memset数组pos了,WA了好长时间。(划掉)
题目中给定了火车的关系,火车停的点都要>=所有点。这种关系比较模棱两可,我们是不是可以知道不停的点一定小于停靠的点呢。答案是肯定的。
我们就把停靠的点和没停靠的点之间连边,然后topsort出最长路经,每次更新一下ans,答案就更新出来啦!
下面是大家喜闻乐见的代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef pair<int,int> P;
const int maxn = 1010;
vector<int> G[maxn];
int a[maxn];
int pos[maxn];
int ind[maxn];
int vis[maxn][maxn];
int ans = 0;
int n,m;
void topsort()
{
queue<P> q;
for(int i=1;i<=n;i++)
{
if(ind[i]==0)
{
q.push(P(i,1));
}
}
while(!q.empty())
{
P tmp = q.front();
q.pop();
for(int i=0;i<G[tmp.first].size();i++)
{
int now = G[tmp.first][i];
ind[now]--;
if(ind[now]==0)
{
q.push(P(now,tmp.second+1));
ans = max(ans,tmp.second+1);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
int s;
for(int k=0;k<m;k++)
{
scanf("%d",&s);
int l = INF;
int r = 0;
memset(pos,0,sizeof(pos));
for(int i=1;i<=s;i++)
{
scanf("%d",a+i);
l = min(l,a[i]);
r = max(r,a[i]);
pos[a[i]] = 1;
}
for(int i=1;i<=s;i++)
{
for(int j=l;j<=r;j++)
{
if(a[i]==j) continue;
if(pos[j]==0 && !vis[a[i]][j])
{
G[a[i]].push_back(j);
ind[j]++;
vis[a[i]][j] = 1;
}
}
}
}
topsort();
cout<<ans<<endl;
return 0;
}