挺好的思路的一个题
Description
在一个长度为 (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();}