zoukankan      html  css  js  c++  java
  • [CF1000E] We Need More Bosses

    Description

    给定一个 (n) 个点 (m) 条边的无向图,找到两个点 (s,t),使得 (s)(t) 必须经过的边最多。

    Solution

    边双内的边显然都不是关键边,否则必是,于是缩点后求直径即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    struct Edge
    {
        int from,next,to;
    } e[N];
    
    vector <int> g[N];
    int n,m,t1,t2,dfn[N],low[N],head[N],bridge[N],bel[N],tot=1,ind,cnt;
    
    void __addedge(int u,int v)
    {
        e[++tot].next=head[u];
        e[tot].to=v;
        head[u]=tot;
    }
    
    void addedge(int u,int v)
    {
        __addedge(u,v);
        __addedge(v,u);
    }
    
    void tarjan(int p,int eid)
    {
        dfn[p]=low[p]=++ind;
        for(int i=head[p];i!=0;i=e[i].next)
        {
            if(i!=(eid^1))
            {
                int q=e[i].to;
                if(!dfn[q])
                {
                    tarjan(q,i);
                    low[p]=min(low[p],low[q]);
                    if(dfn[p]<low[q]) bridge[i]=bridge[i^1]=1;
                }
                else
                {
                    low[p]=min(low[p],dfn[q]);
                }
            }
        }
    }
    
    void dfs(int p,int id)
    {
        bel[p]=id;
        for(int i=head[p];i!=0;i=e[i].next)
        {
            int q=e[i].to;
            if(bel[q]) continue;
            if(!bridge[i]) dfs(q,id);
        }
    }
    
    void presolve()
    {
        for(int i=1;i<=n;i++)
        {
            if(!dfn[i])
            {
                tarjan(i,0);
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(!bel[i])
            {
                dfs(i,++cnt);
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=head[i];j!=0;j=e[j].next)
            {
                int q=e[j].to;
                if(bel[i]!=bel[q])
                {
                    g[bel[i]].push_back(bel[q]);
                    g[bel[q]].push_back(bel[i]);
                }
            }
        }
    }
    
    int dis[N],vis[N];
    
    void dfs2(int p)
    {
        vis[p]=1;
        for(int q:g[p])
        {
            if(!vis[q])
            {
                dis[q]=dis[p]+1;
                dfs2(q);
            }
        }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>t1>>t2;
            addedge(t1,t2);
        }
        presolve();
        dfs2(1);
        int p=max_element(dis+1,dis+n+1)-dis;
        memset(dis,0,sizeof dis);
        memset(vis,0,sizeof vis);
        dfs2(p);
        int q=max_element(dis+1,dis+n+1)-dis;
        cout<<dis[q]<<endl;
    }
    
    
  • 相关阅读:
    TH-Union教学机 指令总结
    Manjaro 显卡驱动安装
    grub学习内容
    manjaro 折腾
    链栈的实现
    汇编综合实验
    二叉树
    Oracle表空间基本操作
    Windows7/10实现ICMP(ping命令)
    WireShark——IP协议包分析(Ping分析IP协议包)
  • 原文地址:https://www.cnblogs.com/mollnn/p/13301835.html
Copyright © 2011-2022 走看看