[LUOGU] P1983 车站分级

维护一群不等关系,除了ywy神犇用的查分约束,不强的关系也可以用拓扑排序解决。

从经过但不停靠的车站向停靠站连边,一定是经过,就是停靠站最先和最后两个之间的车站

然后做一次拓扑排序,记录图的层数,最大层数即为答案。

一点小问题,为什么用栈写的拓扑排序就不对呢?是拓扑排序都应该用队列实现么?

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;

const int MAXN=1024;

inline int rd(){
  int ret=0,f=1;char c;
  while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
  while(isdigit(c))ret=ret*10+c-'0',c=getchar();
  return ret*f;
}

struct Edge{
  int next,to;
}e[MAXN*MAXN];
int ecnt,head[MAXN],ind[MAXN];
inline void add(int x,int y){
  e[++ecnt].next = head[x];
  e[ecnt].to = y;
  head[x] = ecnt;
  ind[y]++;
}

int n,m;
int a[MAXN][MAXN];
int dep[MAXN];

queue<pair<int,int> > Q;

int main(){
  n=rd();m=rd();
  int num,x;
  int lis[MAXN],q[MAXN],p;
  for(int i=1;i<=m;i++){
    num=rd();memset(lis,0,sizeof(lis));p=0;
    int mn=1<<30,mx=-mn;
    for(int j=1;j<=num;j++){
      int x=rd();mn=min(x,mn);mx=max(mx,x);
      lis[x]=1;q[++p]=x;
    }
    for(int j=mn;j<=mx;j++)
      if(!lis[j])
        for(int k=1;k<=p;k++)
          if(a[j][q[k]]) continue;
          else add(j,q[k]),a[j][q[k]]=1;
  }
  int ans=0;
  for(int i=1;i<=n;i++) if(!ind[i]) Q.push(make_pair(i,1));
  while(!Q.empty()){
    int top=Q.front().first,val=Q.front().second;Q.pop();
    ans=max(ans,val);
    for(int i=head[top];i;i=e[i].next){
      int v=e[i].to;
      ind[v]--;
      if(ind[v]==0){Q.push(make_pair(v,val+1));}
    }
  }
  printf("%d",ans);
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/ghostcai/p/9264387.html