BZOJ2182: [Spoj1479]The GbAaY Kingdom最小直径生成树

图的绝对中心..
http://blog.csdn.net/crazy_ac/article/details/8816877

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
using namespace std;

int f[211][211];
int f2[211][211];

inline int Up(int &tp,int M){return tp=min(tp,M);}
char c;
inline void read(int &a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
const
 int INF=1<<29;
int n,m,u,v,w;
bool Us[211][211];
int Sele[211][211];
int main()
{
    read(n),read(m);
      for(int i=1;i<=n;i++)
        for(int j=i;j<=n;j++)
                if(i^j)f2[i][j]=f[i][j]=f2[j][i]=f[j][i]=INF;
                  else f2[i][j]=f[i][j]=0;
    for(int i=1;i<=m;i++)
    {
        read(u),read(v),read(w);
        if(u==v)continue;  
        if(w<f[u][v])  
        {  
            f[u][v] = f[v][u] = w;  
            f2[u][v] = f2[v][u] = w;  
        }  
    }
    for(int k=1;k<=n;k++)
      for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
     for(int i=1;i<=n;i++)
     {
        for(int j=1;j<=n;j++)Sele[i][j]=j;
        for(int j=1;j<n;j++)
             for(int k=j+1;k<=n;k++)
                if(f[i][Sele[i][j]]>f[i][Sele[i][k]])swap(Sele[i][j],Sele[i][k]);
     }
     int ans=INF;
    for(int u=1;u<=n;u++)  
    {  
        for(int v=1;v<=n;v++)
        if(f2[u][v])  
        {  
            ans=min(ans,f[u][Sele[u][n]]<<1);  
            ans=min(ans,f[v][Sele[v][n]]<<1);  
            for(int cmp=n,i=n-1;i>=1;i--)  
                if(f[v][Sele[u][i]]>f[v][Sele[u][cmp]])  
                    ans=min(ans,f[u][Sele[u][i]]+f[v][Sele[u][cmp]]+f2[u][v]),cmp=i;
        }  
    }  
    printf("%d\n",ans); 
    return 0;
}

你可能感兴趣的:(BZOJ2182: [Spoj1479]The GbAaY Kingdom最小直径生成树)