zoukankan      html  css  js  c++  java
  • 【DFS】Gym

    给你一个森林,让你把它连接成一颗树,使得直径最小。

    就求出每颗树的重心以后,全都往直径最大的那个的重心上连,一般情况是最大/2+次大/2+1,次大/2+第三大/2+2 中取较大者。

    还有些特殊情况要特判处理一下。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int v[200010],first[100010],next[200010],e;
    void AddEdge(int U,int V){
    	v[++e]=V;
    	next[e]=first[U];
    	first[U]=e;
    }
    int n,m;
    int S1;
    bool vis[100010],vis2[100010];
    int maxD;
    void dfs(int U,int d){
    	vis[U]=1;
    	if(d>maxD){
    		maxD=d;
    		S1=U;
    	}
    	for(int i=first[U];i;i=next[i]){
    		if(!vis[v[i]]){
    			dfs(v[i],d+1);
    		}
    	}
    }
    void df2(int U,int d){
    	vis2[U]=1;
    	maxD=max(maxD,d);
    	for(int i=first[U];i;i=next[i]){
    		if(!vis2[v[i]]){
    			df2(v[i],d+1);
    		}
    	}
    }
    int b[100010],be;
    int main(){
    //	freopen("a.in","r",stdin);
    	int x,y;
    	scanf("%d%d",&n,&m);
    	if(n==1){
    		puts("0");
    		return 0;
    	}
    	if(n==2){
    		puts("1");
    		return 0;
    	}
    	for(int i=1;i<=m;++i){
    		scanf("%d%d",&x,&y);
    		++x;
    		++y;
    		AddEdge(x,y);
    		AddEdge(y,x);
    	}
    	for(int i=1;i<=n;++i){
    		if(!vis[i]){
    			maxD=0;
    			dfs(i,0);
    			maxD=0;
    			df2(S1,0);
    			b[++be]=maxD;
    		}
    	}
    	sort(b+1,b+be+1);
    	int tmp=max(2,max(b[be]/2+b[be]%2+b[be-1]/2+b[be-1]%2+(be!=1),b[be]));
    	if(be>=3){
    		tmp=max(tmp,b[be-2]/2+b[be-2]%2+b[be-1]/2+b[be-1]%2+2);
    	}
    	printf("%d
    ",tmp);
    	return 0;
    }
  • 相关阅读:
    洛谷p1056
    __int64
    杭电2057
    4.4清北学堂Day1 主要内容:数论,数学
    递推的一点理解
    高精度减法
    高精度加法
    p1184高手之在一起
    对于rqy今天讲座的一些理解和看法吧
    PHP.21-商品信息管理
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7219592.html
Copyright © 2011-2022 走看看