思维好题
考虑从topo序入手,枚举删点x
x之前的点在S,之后的在T
删除这个点后,剩下的路径是:S中的,T中的,S经过一条集合之间的边到T的
两遍topo排序得到diss,dist从x出发和到x结束的最长路
三种路径分别用堆维护
步骤:
把x的前驱到x的都删掉,把x在T的删掉,统计最大值
把x在S的加入,x到x的后继都加入
#include<bits/stdc++.h> #define reg register int #define il inline #define fi first #define se second #define mk(a,b) make_pair(a,b) #define numb (ch^'0') #define pb push_back #define solid const auto & #define enter cout<<endl #define pii pair<int,int> using namespace std; typedef long long ll; template<class T>il void rd(T &x){ char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);} template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');} template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');} template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar(' ');} namespace Modulo{ const int mod=998244353; int ad(int x,int y){return (x+y)>=mod?x+y-mod:x+y;} void inc(int &x,int y){x=ad(x,y);} int mul(int x,int y){return (ll)x*y%mod;} void inc2(int &x,int y){x=mul(x,y);} int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;} } //using namespace Modulo; namespace Miracle{ const int N=500000+5; const int M=1000000+5; const int inf=0x3f3f3f3f; int n,m; struct node{ int nxt,to; }e[2*M]; int hd[2][N],cnt[2]; int du[2][N]; void add(int x,int y,int c){ e[++cnt[c]].nxt=hd[c][x]; e[cnt[c]].to=y;hd[c][x]=cnt[c]; ++du[c][y]; } int diss[N],dist[N]; int q[N],l,r; int rk[N],id[N],df; bool cmp(int x,int y){ return rk[x]<rk[y]; } void topo(int *hd,int *dis,int *du){ l=1;r=0; memset(rk,0,sizeof rk); df=0; for(reg i=1;i<=n;++i){ if(du[i]==0) { q[++r]=i;dis[i]=0; } } while(l<=r){ int x=q[l++]; // cout<<" xx "<<x<<endl; rk[x]=++df; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; // cout<<" yy "<<y<<endl; du[y]--; dis[y]=max(dis[y],dis[x]+1); if(du[y]==0){ q[++r]=y; } } } } struct heap{ priority_queue<int>q,d; void push(int x){q.push(x);} void dele(int x){d.push(x);} int top(){ while(!q.empty()&&!d.empty()&&q.top()==d.top()) q.pop(),d.pop(); if(q.size()) return q.top(); return -inf; } }q1,q2,q3; int main(){ rd(n);rd(m); int x,y; cnt[1]=m; for(reg i=1;i<=m;++i){ rd(x);rd(y); add(x,y,0);add(y,x,1); } // prt(du[0],1,n); // prt(hd[0],1,n); // cout<<cnt[0]<<endl; // enter;enter; topo(hd[1],diss,du[1]); // enter; topo(hd[0],dist,du[0]); // prt(diss,1,n); // prt(dist,1,n); for(reg i=1;i<=n;++i){ id[i]=i; q3.push(diss[i]); } sort(id+1,id+n+1,cmp); int ans=inf; int de=0; for(reg p=1;p<=n;++p){ int x=id[p]; for(reg i=hd[1][x];i;i=e[i].nxt){ int y=e[i].to; q2.dele(diss[x]+dist[y]+1); } q3.dele(diss[x]); int now=max(q1.top(),max(q2.top(),q3.top())); // cout<<" x "<<x<<" now "<<now<<endl; if(ans>now){ ans=min(ans,now); de=x; } q1.push(dist[x]); for(reg i=hd[0][x];i;i=e[i].nxt){ int y=e[i].to; q2.push(dist[x]+diss[y]+1); } } // ot(ans);ot(de); ot(de);ot(ans); return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* */