喵喵喵
新建点st连向所有点,所有点连向点ed,f[i]表示S到i的最长链,g[i]表示i到T的最长链,那么过一条边< u,v>的最长链就是f[u]+< u,v>+g[v],将这个定义为边权,那么原图任意一个割集中最大的边权就是图中的最长链
按拓扑序枚举删的点,一开始原图分成st和其他点这两个集合S,T,每次选出T中一个可拓展的点v,将割集中连向v的边删掉,剩余的最大边权就是删去v的答案,再将v加入S集,割集中加入v的出边
资瓷添加删除和询问最大值,用堆就可以了
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
inline void read(int &x)
{
char c;while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
inline void up(int &x,const int &y){if(x<y)x=y;}
inline void down(int &x,const int &y){if(x>y)x=y;}
const int maxn = 1100000;
const int maxm = 2100000;
int n,m;
int e[maxm][2],cnt;
int f[maxn],g[maxn];
vector<int>V1[maxn],V2[maxn];
int ind[maxn];
queue<int>q;
struct node{int ei,x;}; bool v[maxm];
inline bool operator <(const node x,const node y){return x.x<y.x;}
priority_queue<node>Q;
void push(const int ei) { v[ei]=true; Q.push((node){ei,f[e[ei][0]]+g[e[ei][1]]}); }
void del(const int ei) { v[ei]=false; }
int Top()
{
while(!Q.empty())
{
const node now=Q.top();
if(!v[now.ei]) { Q.pop(); continue; }
return now.x;
}
return n;
}
int ans,ansi;
int main()
{
read(n); read(m); ans=n+1;
for(int i=1;i<=m;i++)
{
int x,y; read(x); read(y);
++cnt; e[cnt][0]=x,e[cnt][1]=y;
V1[x].push_back(cnt);
V2[y].push_back(cnt);
}
for(int i=1;i<=n;i++)
{
++cnt; e[cnt][0]=n+1,e[cnt][1]=i;
V1[n+1].push_back(cnt);
V2[i].push_back(cnt);
++cnt; e[cnt][0]=i,e[cnt][1]=n+2;
V1[i].push_back(cnt);
V2[n+2].push_back(cnt);
}n+=2;
for(int i=1;i<=n;i++) for(int j=0;j<V1[i].size();j++)
ind[e[V1[i][j]][1]]++;
q.push(n-1); f[n-1]=0;
while(!q.empty())
{
const int x=q.front(); q.pop();
for(int i=0;i<V1[x].size();i++)
{
int y=e[V1[x][i]][1]; up(f[y],f[x]+1);
ind[y]--; if(!ind[y]) q.push(y);
}
}
for(int i=1;i<=n;i++) for(int j=0;j<V2[i].size();j++)
ind[e[V2[i][j]][0]]++;
q.push(n); g[n]=0;
while(!q.empty())
{
const int x=q.front(); q.pop();
for(int i=0;i<V2[x].size();i++)
{
int y=e[V2[x][i]][0]; up(g[y],g[x]+1);
ind[y]--; if(!ind[y]) q.push(y);
}
}
for(int i=1;i<=n;i++) for(int j=0;j<V1[i].size();j++)
ind[e[V1[i][j]][1]]++;
q.push(n-1);
while(!q.empty())
{
const int x=q.front(); q.pop();
for(int i=0;i<V2[x].size();i++) del(V2[x][i]);
int tmp=Top();
if(ans>tmp) ansi=x,ans=tmp;
for(int i=0;i<V1[x].size();i++)
{
int ei=V1[x][i],y=e[ei][1];
ind[y]--; if(!ind[y]) q.push(y);
push(ei);
}
}
printf("%d %d\n",ansi,ans-1);
return 0;
}