zoukankan      html  css  js  c++  java
  • 【tarjan】【树的直径】【CF】K. Königsberg Bridges

    【tarjan】【树的直径】【CF】K. Königsberg Bridges

    image

    题目传送门

    #include <bits/stdc++.h>
    #define MEM(a,x) memset(a,x,sizeof(a))
    #define W(a) while(a)
    #define gcd(a,b) __gcd(a,b)
    #define pi acos(-1.0)
    #define PII pair<int,int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define ull unsigned long long
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define MAX 1000005
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    #define lowbit(x) (x&-x)
    #define de(x) cout<<"debug : "<<x<<endl
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0' && ch<='9')
            x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const int N = 1E6+100, M = 2E6+100;
    struct edge{
    	int u,v,nxt;
    }edges[M],edges_scc[M];
    
    int idx,h[N];
    void add_edge(int u,int v) 
    {
    	edges[idx] = {u,v,h[u]};
    	h[u] = idx++;
    }
    
    int idx_scc,h_scc[N];
    void add_scc(int u,int v)
    {
    	edges_scc[idx_scc] = {u,v,h_scc[u]};
    	h_scc[u] = idx_scc++;
    }
    int low[N],dfn[N],time_stamp,scc_cnt,bel[N];
    bool in_st[N],is_bridge[M];
    stack<int > st;
    vector<int > scc[N];
    void tarjan(int u,int from)
    {
    
    	dfn[u] = low[u] = ++time_stamp;
            in_st[u] = true;
    	st.push(u);
    	for(int i = h[u];~i;i=edges[i].nxt)
    	{
    		int v = edges[i].v;
    	  
    		if(!dfn[v])
    		{ 
    			tarjan(v,i);
    			low[u] = min(low[v],low[u]);
    			if(dfn[u]<low[v])
    			   is_bridge[i] = is_bridge[i^1] = 1;
    		}
    		else if(i!=(from^1))
    		    low[u] = min(low[v],low[u]);
    	}
    	if(dfn[u]==low[u])
    	{
    		int t;
    	        do{
    			t = st.top();
    			st.pop();
    			in_st[t] = false;
    			scc[scc_cnt].push_back(t);
    			bel[t] = scc_cnt;
    		}while(t!=u);
    		scc_cnt++;
    	}
    }
    int max_len,max_v;
    bool used[N];
    void dfs(int u,int fa,int dep)
    {
    	used[u] = true;
    	if(dep>max_len)
    	{
    		max_v = u;
    		max_len = dep;	
    	}
    	for(int i = h_scc[u];~i;i=edges_scc[i].nxt)
    	{
    		if(edges_scc[i].v==fa) continue;
    		dfs(edges_scc[i].v,u,dep+1);
    	}
    }
    int main()
    {
    	int n = read(),m = read();
    	memset(h,-1,sizeof(h));
    	memset(h_scc,-1,sizeof(h_scc));
    
    	for(int i=0;i<m;i++)
    	{
    		int u = read(),v = read();
    		add_edge(u,v);add_edge(v,u);
    	}
    
    	for(int i=0;i<n;i++)
    	    if(!dfn[i])
    	       tarjan(i,-1);
         
    	for(int i=0;i<idx;i+=2)
    	   if(is_bridge[i])
    	   	  add_scc( bel[edges[i].u], bel[edges[i].v] ),add_scc( bel[edges[i].v],bel[edges[i].u]);
    	
        int ans = 0,blocks = 0;
        for(int i=0;i<scc_cnt;i++)
        {
        	if(!used[i])
        	{
        		blocks ++;
        		max_len = 0,max_v = i;//直径的点要初始化好,不然还是停留在上一轮 
        		dfs(i,-1,0);
        		max_len = 0;
         		dfs(max_v,-1,0);
        		ans += max_len;
    		}
    	}
    	cout<<ans+blocks-1;
            return 0;
    }
    
    
  • 相关阅读:
    机器学习笔记之Boosting算法
    机器学习笔记之多重共线性问题以及如何解决
    机器学习笔记之在Visual Studio Code中使用Jupyter Notebook
    高数学习笔记之范数与距离度量(python实现)
    机器学习笔记之线性回归最小二乘法(公式推导和非调包实现)
    机器学习笔记之线性回归数学推导
    高数笔记之期望、方差与最小二乘法
    DataTable 去重 测试
    vs2019 项目历史记录
    sql 求和 语句
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15549482.html
Copyright © 2011-2022 走看看