分析
我还以为是什么奇怪的东西呢,点就四个
我们只需要预处理出距离每个点最远和次远的点的距离和点,然后枚举四个点中间的两个点,先选择它们的最远点,若最远点重合,则选次远点
#include <iostream> #include <cstdio> #include <memory.h> #include <queue> using namespace std; const int N=3e3+10; const int Inf=0x3f3f3f3f; struct Edge { int u,v,nx; }g[2*N]; int cnt,list[N],d[N][N],mx[N][2],revmx[N][2]; int n,m; void Add(int u,int v) { g[++cnt]=(Edge){u,v,list[u]};list[u]=cnt; } void BFS() { queue<int> from,to; while (!from.empty()) from.pop(); while (!to.empty()) to.pop(); for (int i=1;i<=n;i++) d[i][i]=0,from.push(i),to.push(i); while (!from.empty()) { int f=from.front(),u=to.front();from.pop();to.pop(); for (int i=list[u];i;i=g[i].nx) if (d[f][g[i].v]>d[f][u]+1) { d[f][g[i].v]=d[f][u]+1; from.push(f);to.push(g[i].v); } } } void Pre_Process() { for (int i=1;i<=n;i++) { mx[i][0]=mx[i][1]=revmx[i][0]=revmx[i][1]=i; for (int j=1;j<=n;j++) if (i!=j) { if (d[i][j]!=Inf) if (d[i][j]>d[i][mx[i][0]]) mx[i][1]=mx[i][0],mx[i][0]=j; else if (d[i][j]>mx[i][1]) mx[i][1]=j; if (d[j][i]!=Inf) if (d[j][i]>d[revmx[i][0]][i]) revmx[i][1]=revmx[i][0],revmx[i][0]=j; else if (d[j][i]>d[revmx[i][1]][i]) revmx[i][1]=j; } } } int main() { scanf("%d%d",&n,&m); for (int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),Add(u,v); memset(d,0x3f,sizeof d);BFS(); Pre_Process(); int ans=0,a1,a2,a3,a4; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i!=j&&d[i][j]!=Inf) for (int k=0;k<2;k++) for (int l=0;l<2;l++) { int u1=revmx[i][k],v1=mx[j][l]; if (u1==v1||u1==i||u1==j||v1==i||v1==j) continue; if (d[u1][i]+d[i][j]+d[j][v1]>ans) ans=d[u1][i]+d[i][j]+d[j][v1],a1=u1,a2=i,a3=j,a4=v1; } printf("%d %d %d %d ",a1,a2,a3,a4); }