题意:给一个非连通图,将所有非连通图连接成一个连通图,求最终的连通图最小直径,
解;将每个连通图直径求出来,按照从大到小顺序排列, D=(d0+1)/2+(d1+1)/2+1,当d0==d1==d2 时,D=D=(d0+1)/2+(d1+1)/2+1,
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=100000+1000;
struct Edge
{
int v,next;
} edge[2*maxn];
int tot,head[maxn];
int vis[maxn],vis2[maxn],vis1[maxn];
int dis[maxn],d[maxn];;
void init()
{
tot=0;
memset(head,-1,sizeof(head));
}
void add_edge(int u,int v)
{
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
edge[tot].v=u;
edge[tot].next=head[v];
head[v]=tot++;
}
int bfs(int S)
{
queue<int>que;
que.push(S);
vis[S]=1;
dis[S]=0;
int s,max_v=-10;
int u;
while(!que.empty())
{
u=que.front();
que.pop();
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
if(!vis[v])
{
vis[v]=1;
dis[v]=dis[u]+1;
que.push(v);
if(dis[v]>max_v)
{
max_v=dis[v];
s=v;
}
}
}
}
while(!que.empty())
que.pop();
memset(vis2,0,sizeof(vis2));
vis2[s]=1;
que.push(s);
dis[s]=0;
max_v=-10;
while(!que.empty())
{
u=que.front();
que.pop();
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
if(!vis2[v])
{
vis2[v]=1;
dis[v]=dis[u]+1;
que.push(v);
if(dis[v]>max_v)
max_v=dis[v];
}
}
}
return max_v;
}
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int n,m;
int u,v,temp;
int tol,max_v;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
memset(d,0,sizeof(d));
memset(vis1,0,sizeof(vis1));
memset(vis,0,sizeof(vis));
for(int i=0; i<m; i++)
{
scanf("%d%d",&u,&v);
add_edge(u,v);
vis1[u]=1;
vis1[v]=1;
}
tol=0,max_v=0;
for(int i=0; i<n; i++)
{
if(vis[i]==0&&vis1[i]!=0)
{
temp=bfs(i);
if(temp >max_v)
max_v=temp;
d[tol++]=(temp+1)>>1;
}
}
sort(d,d+tol,cmp);
if(n<=2)
printf("%d\n",n-1>=0?n-1:0);
else if(tol==0)
printf("2\n");
else if(tol>=3&&d[0]==d[1]&&d[1]==d[2])
printf("%d\n",max(max_v,d[0]+d[1]+2));
else
printf("%d\n",max(max_v,d[0]+d[1]+1));
}
return 0;
}