我不会啊
老老实实去学吧 求图的绝对中心 && 最小直径生成树 MDST
绝对重心呢 就是枚举每一条边 然后从这条边上某个坐标 到所有点的最小距离是一条折线
然后用这一组折线乱搞就好了
怎么求MDST呢 从绝对重心跑一边最短路径树就好了
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=205;
int d[N][N],w[N][N],rk[N][N];
int n,m;
int main(){
int iu,iv,iw;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) w[i][j]=d[i][j]=1<<29;
for (int i=1;i<=n;i++) w[i][i]=d[i][i]=0;
for (int i=1;i<=m;i++)
scanf("%d%d%d",&iu,&iv,&iw),w[iu][iv]=min(w[iu][iv],iw),w[iv][iu]=d[iu][iv]=d[iv][iu]=w[iu][iv];
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++) rk[i][j]=j;
for (int j=1;j<=n;j++)
for (int k=j+1;k<=n;k++)
if (d[i][rk[i][j]]>d[i][rk[i][k]])
swap(rk[i][k],rk[i][j]);
}
int ans=1<<30;
for (int u=1;u<=n;u++)
for (int v=1;v<=n;v++){
if (u==v || w[u][v]==1<<29) continue;
ans=min(ans,min(d[u][rk[u][n]]<<1,d[v][rk[v][n]]<<1));
for (int last=n,i=n-1;i;i--)
if (d[v][rk[u][i]]>d[v][rk[u][last]])
ans=min(ans,d[u][rk[u][i]]+d[v][rk[u][last]]+w[u][v]),last=i;
}
printf("%d\n",ans);
return 0;
}
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=205;
int d[N][N],w[N][N],rk[N][N];
int n,m;
int s1,s2;
inline int Find(){
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++) rk[i][j]=j;
for (int j=1;j<=n;j++)
for (int k=j+1;k<=n;k++)
if (d[i][rk[i][j]]>d[i][rk[i][k]])
swap(rk[i][k],rk[i][j]);
}
int ans=1<<30;
for (int u=1;u<=n;u++)
for (int v=1;v<=n;v++){
if (u==v || w[u][v]==1<<30) continue;
if ((d[u][rk[u][n]]<<1)<ans) ans=d[u][rk[u][n]]<<1,s1=s2=u;
if ((d[v][rk[v][n]]<<1)<ans) ans=d[v][rk[v][n]]<<1,s1=s2=v;
for (int last=n,i=n-1;i;i--)
if (d[v][rk[u][i]]>d[v][rk[u][last]]){
if (d[u][rk[u][i]]+d[v][rk[u][last]]+w[u][v]<ans)
ans=d[u][rk[u][i]]+d[v][rk[u][last]]+w[u][v],s1=u,s2=v;
last=i;
}
}
return ans;
}
int Q[N],l,r;
int dis[N],pre[N];
inline void bfs(){
for (int i=1;i<=n;i++) dis[i]=-1;
l=r=-1; Q[++r]=s1; dis[s1]=0;
if (s1!=s2)
Q[++r]=s2,dis[s2]=0,pre[s2]=s1;
while (l<r){
int u=Q[++l];
for (int i=1;i<=n;i++)
if (w[u][i]==1 && dis[i]==-1)
dis[i]=dis[u]+1,Q[++r]=i,pre[i]=u;
}
}
int main(){
int iu,iv,iw;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) w[i][j]=d[i][j]=1<<29;
for (int i=1;i<=n;i++) w[i][i]=d[i][i]=0;
for (int i=1;i<=m;i++)
scanf("%d%d",&iu,&iv),w[iu][iv]=w[iv][iu]=d[iu][iv]=d[iv][iu]=1;
Find(); bfs();
for (int i=1;i<=n;i++)
if (pre[i])
printf("%d %d\n",i,pre[i]);
return 0;
}