思路是两遍 dp 跑出到某个点为止最长路和从某个点开始的最长路,然后拓扑一下,把拓扑序扔进线段树里,枚举每条边,做区间 min/max 操作,理论时间复杂度是 O(mlogn) 的,然而 T 了 5 个点,甚至是毫不相干的 5 个点,故此求助。
感觉是某个地方出死循环的 bug,然而我没找到。
#include <iostream>
#include <algorithm>
#include <vector>
#define ll int
#define lc (x<<1)
#define rc (x<<1|1)
#define mid ((l+r)>>1)
using namespace std;
const ll N=5e5+10;
const ll INF=2147483647;
ll mn[N<<2],cnt[N<<2],se[N<<2],tag[N<<2],a[N],Dt[N<<2];
inline void push_up(ll x){
if(mn[lc]==mn[rc]){
mn[x]=mn[lc],cnt[x]=cnt[lc]+cnt[rc];
se[x]=min(se[lc],se[rc]);
Dt[x]=Dt[lc];
}
else{
if(mn[lc]<mn[rc]) mn[x]=mn[lc],cnt[x]=cnt[lc],Dt[x]=Dt[lc];
else mn[x]=mn[rc],cnt[x]=cnt[rc],Dt[x]=Dt[rc];
se[x]=min(max(mn[lc],mn[rc]),min(se[lc],se[rc]));
}
}
void build(ll x,ll l,ll r){
tag[x]=-1;
if(l==r){
cnt[x]=1,se[x]=INF;
mn[x]=a[l];Dt[x]=l;
return;
}
build(lc,l,mid);
build(rc,mid+1,r);
push_up(x);
}
inline void update(ll x,ll k){if(k>mn[x]) mn[x]=k,tag[x]=k;}
inline void push_down(ll x){
if(tag[x]!=-1){
update(lc,tag[x]);
update(rc,tag[x]);
tag[x]=-1;
}
}
void chg(ll x,ll L,ll R,ll l,ll r,ll k){
if(mn[x]>=k) return;
if(L<=l&&r<=R&&se[x]>k){update(x,k);return;}
push_down(x);
if(L<=mid) chg(lc,L,R,l,mid,k);
if(R>mid) chg(rc,L,R,mid+1,r,k);
push_up(x);
}
inline ll read(){
register ll x=0,f=1;
register char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
ll n,m,x,y,in[N],edd[N],stt[N],q[N],front,rear;
ll DTuo[N],TuoD[N],tot;
vector<ll> edge[N];
void dfs(ll u){
ll lz=edge[u].size();
if(!lz) return;
for(ll i=0;i<lz;i++){
dfs(edge[u][i]);
stt[u]=max(stt[u],stt[edge[u][i]]+1);
}
}
int main(){
n=read(),m=read();
for(ll i=1;i<=m;i++){
x=read(),y=read();
edge[x].push_back(y);
in[y]++;
}
for(ll i=1;i<=n;i++) if(!in[i]) dfs(i),q[++rear]=i;
while(front<rear){
ll now=q[++front],lz=edge[now].size();
DTuo[now]=++tot;
TuoD[tot]=now;
for(ll i=0;i<lz;i++){
in[edge[now][i]]--;
edd[edge[now][i]]=max(edd[edge[now][i]],edd[now]+1);
if(!in[edge[now][i]]) q[++rear]=edge[now][i];
}
}
for(ll i=1;i<=n;i++){
a[DTuo[i]]=edd[i];
q[DTuo[i]]=stt[i];
}
for(ll i=1;i<=n;i++){
edd[i]=a[i];
stt[i]=q[i];
//cout<<TuoD[i]<<' '<<edd[i]<<' '<<stt[i]<<"\n";
}
ll mx=0;
for(ll i=1;i<=n;i++) a[i]=mx,mx=max(mx,edd[i]);
mx=0;
for(ll i=n;i>=1;i--) a[i]=max(a[i],mx),mx=max(mx,stt[i]);
//for(ll i=1;i<=n;i++) cout<<a[i]<<" ";
//cout<<"\n";
build(1,1,n);
for(ll i=1;i<=n;i++){
ll lz=edge[i].size(),from,to;
for(ll j=0;j<lz;j++){
from=DTuo[i],to=DTuo[edge[i][j]];
if(from>to) swap(from,to);
if(from+1==to) continue;
//cout<<from+1<<"->"<<to-1<<":"<<edd[from]+1+stt[to]<<"\n";
chg(1,from+1,to-1,1,n,edd[from]+1+stt[to]);
}
}
x=TuoD[Dt[1]],y=mn[1];
cout<<x<<' '<<y;
return 0;
}