NOIP2016(PJT4) 车站分级

挺好的思路的一个题

Description

link

在一个长度为 \(n\) 的序列上每一个数都有一个优先级,然后我们给出 \(m\) 条限制

每个限制组中的数的优先级必须大于等于同组数的优先级

问最小的\(max\)优先级

\(n,m \leq 1000\)

Solution

还是点链接看原题吧,博主的题意概述分别指向了二分和差分约束

然而这个是一个拓扑题

读题读题读题我们发现:在这个路线上(原题中提到了这个概念)没有停靠的点的优先级比数列中任何一个都小

然后建图,跑拓扑序,这题没了

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
    inline int read()
    {
        int res=0,f=1; char k;
        while(!isdigit(k=getchar())) if(k=='-') f=-1;
        while(isdigit(k)) res=res*10+k-'0',k=getchar();
        return res*f;
    }
    const int N=1010;
    struct node{
        int to,nxt;
    }e[N<<9];
    int head[N],num[N],n,m,cnt,st[N][N],in[N],ans,res[N];
    bool fl[N],vis[N][N];
    inline void add(int u,int v)
    {
        e[++cnt].nxt=head[u]; e[cnt].to=v;
        return head[u]=cnt,void();
    }  
    queue<int> q;
    signed main()
    {
        n=read(); m=read();
        for(int i=1;i<=m;++i)
        {
            num[i]=read(); memset(fl,0,sizeof(fl));
            for(int j=1;j<=num[i];++j)
            {
                st[i][j]=read(); fl[st[i][j]]=1;
            }
            for(int j=st[i][1];j<=st[i][num[i]];++j)
            {
                if(fl[j]) continue;
                for(int k=1;k<=num[i];++k)
                {
                    if(!vis[j][st[i][k]])
                    {
                        add(j,st[i][k]); in[st[i][k]]++; vis[j][st[i][k]]=1;
                    }
                }
            }
        }   
        for(int i=1;i<=n;++i) if(!in[i]) q.push(i),res[i]=1;
        while(!q.empty())
        {
            int fr=q.front(); q.pop(); ans=max(ans,res[fr]);
            for(int i=head[fr];i;i=e[i].nxt)
            {
                int t=e[i].to; in[t]--;
                if(!in[t]) res[t]=res[fr]+1,q.push(t);
            }
        }
        return cout<<ans<<endl,0;
    }
}
signed main(){return yspm::main();} 

猜你喜欢

转载自www.cnblogs.com/yspm/p/12508386.html