zoukankan      html  css  js  c++  java
  • cf1000E

     先缩点构造出一颗树,然后求树的直径就好

    const int maxn=3e5+5;
    const int maxm=6e5+5;
    const int inf=1e9;
    
    int head[maxn],ver[maxm],nex[maxm],tot;
    
    void inline AddEdge(int x,int y){
    	ver[++tot]=y,nex[tot]=head[x],head[x]=tot;
    }
    
    int n,m;
    
    bool bridge[maxm];
    
    int dfn[maxn],low[maxn];
    
    int num;
    
    void Tarjan(int x,int edge){
    	//cout<<x<<endl;
    	dfn[x]=low[x]=++num;
    	for(int i=head[x];i;i=nex[i]){
    		int y=ver[i];
    		if(!dfn[y]){
    			Tarjan(y,i);
    			low[x]=min(low[x],low[y]);
    			if(low[y]>dfn[x])
    				bridge[i]=bridge[i^1]=1;
    		}
    		else if(i!=(edge^1)) 
    			low[x]=min(low[x],dfn[y]);
    	}
    }
    
    int id[maxn],bcc;
    
    namespace solve{
    	int head[maxn],ver[maxm],nex[maxm],tot;
    
    	void inline AddEdge(int x,int y){
    		ver[++tot]=y,nex[tot]=head[x],head[x]=tot;
    	}
    
    	int f1[maxn],f2[maxn];
    	
    	int ans;
    	
    	int dfs(int x,int pa){
    		f1[x]=f2[x]=0;
    		for(int i=head[x];i;i=nex[i]){
    			int y=ver[i];
    			if(y==pa) continue;
    			dfs(y,x);
    			if(f1[x]<f1[y]+1){
    				f2[x]=f1[x];
    				f1[x]=f1[y]+1;
    			}
    			else if(f2[x]<f1[y]+1){
    				f2[x]=f1[y]+1;
    			}
    		}
    		ans=max(ans,f1[x]+f2[x]);
    		return ans;
    	}
    
    };
    
    void dfs(int x,int pa){
    	id[x]=bcc;
    	for(int i=head[x];i;i=nex[i]){
    		int y=ver[i];
    		if(y==pa || bridge[i] || id[y]) continue;
    		dfs(y,pa);
    	}
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	tot=1;
    	for(int i=0;i<m;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		AddEdge(x,y);
    		AddEdge(y,x);
    	}
    	for(int i=1;i<=n;i++)
    		if(!dfn[i]) Tarjan(i,0);
    //	for(int i=1;i<=n;i++)
    //		cout<<low[i]<<' '<<i<<endl;
    	for(int i=1;i<=n;i++)
    		if(!id[i]) bcc++,dfs(i,0);
    //	cout<<bcc<<endl;
    //	for(int i=1;i<=n;i++)
    //		cout<<id[i]<<endl;
    	for(int i=2;i<=tot;i+=2){
    		if(bridge[i]) {
    			solve::AddEdge(id[ver[i]],id[ver[i^1]]);
    			solve::AddEdge(id[ver[i^1]],id[ver[i]]);
    //			cout<<id[ver[i]]<<' '<<id[ver[i^1]]<<endl;
    		}
    	}
    	cout<<solve::dfs(1,0)<<endl;
    }
    

      

  • 相关阅读:
    Nginx创建密码保护目录
    Android:Field can be converted to a local varible.
    创建用户故事地图(User Story Mapping)的8个步骤
    用户故事地图(User Story Mapping)之初体验
    Android必知必会--GreenDao缓存
    Windows下多线程数据同步互斥的有关知识
    OpenCV3.0 3.1版本的改进
    利用OpenCV的人脸检测给头像带上圣诞帽
    一些关于并行计算的科研思路
    Java中httpClient中三种超时设置
  • 原文地址:https://www.cnblogs.com/033000-/p/12323013.html
Copyright © 2011-2022 走看看