题意:给一个有向图 求出4个点最短距离和最大 (n<=3e3)
d(a+b+c+d)要最大 枚举b,c 因为路程要最大 找到离b最远a和离c最远d即可
#include <bits/stdc++.h>
#include <queue>
#include <vector>
using namespace std;
const int N=5e3+20;
const long long inf=2e7;
vector<int> e[N];
int n,m,A,B,C,Y;
int d[N][N],vis[N],used[N];
int ans=0;
struct node{
int d,to;
};
bool cmp(node a,node b)
{
return a.d>b.d;
}
vector<node> p1[N],p2[N];
void bfs(int x)
{
memset(vis,0,sizeof(vis));
queue<int> q;
q.push(x);
vis[x]=1;
d[x][x]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
if(d[x][u]<inf&&d[x][v]>d[x][u]+1)
{
d[x][v]=d[x][u]+1;
vis[v]=1;
q.push(v);
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=inf;
while(m--)
{
int u,v;
cin>>u>>v;
e[u].push_back(v);//单向无权
}
for(int i=1;i<=n;i++)
bfs(i);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(d[i][j]!=inf&&i!=j)
{
p1[i].push_back((node){d[i][j],j});//c->d
p2[j].push_back((node){d[i][j],i});//a->b
}
}
}
//提前排序:快速找到最大的d[i][j]
for(int i=1;i<=n;i++)
{
sort(p1[i].begin(),p1[i].end(),cmp);
sort(p2[i].begin(),p2[i].end(),cmp);
}
int ans=0;
for(int b=1;b<=n;b++)
{
for(int c=1;c<=n;c++)
{
if(b==c||d[b][c]>=inf) continue;
//枚举前4大的,防止离b最近的是c或者是d
for(int i=0;i<p2[b].size()&&i<4;i++)
{
if(p2[b][i].to==c) continue;//a=(c)->b路径
for(int l=0;l<p1[c].size()&&l<4;l++)
{
if(p1[c][l].to==p2[b][i].to|| p1[c][l].to==b) continue;
int res=p2[b][i].d+d[b][c]+p1[c][l].d;
if(res>ans)
{
ans=res;
A=p2[b][i].to;
B=b;
C=c;
Y=p1[c][l].to;
}
}
}
}
}
printf("%d %d %d %d\n",A,B,C,Y);
return 0;
}