zoukankan      html  css  js  c++  java
  • [JZOJ 5465] [NOIP2017提高A组冲刺11.9] 道路重建 解题报告 (e-dcc+树的直径)

    题目链接:

    http://172.16.0.132/senior/#main/show/5465

    题目:

    小X所居住的X国共有n个城市,有m条无向道路将其连接。作为一个统一的国家,X 城的任意两个城市都可以相互到达。
    由于X国正处于地震带上,有时X国中会有至多一条道路发生毁坏,无法使用。如果这条道路的毁坏恰好阻断了某些城市的往来,那么我们称这条道路是危险的。
    人们并不喜欢危险的道路,于是人们决定重建恰好一条道路,以减少危险的道路数。请告诉人们,重建恰好一条道路后,危险的道路数最少是多少。

    题解:

    显然在一个边双里,任意删掉一条边依旧是连通的,也就是说危险的道路其实就是桥

    因此我们缩边双,建新图

    注意到缩掉所有的边双之后图会变成一棵树,我们就是要在这棵树连边,使得上形成的环最大,环上的边本来是危险的,现在不危险了

    显然我们要连的是直径的两个端点,求一遍树的直径就好了

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<time.h>
    #define mem(x,y) memset(x,y,sizeof(x))
    using namespace std;
    
    const int N=2e5+15;
    const int M=1e6+15;
    int n,m,tot1,tot2,tim,tp,mx,pos;
    int h1[N],h2[N],dfn[N],vis[N],belong[N],low[N];
    bool brige[M<<1];
    struct E{
        int to,nxt;
    }e1[M<<1],e2[M<<1];
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int read(){
        char ch=nc();int s=0,f=1;
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=nc();}
        while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=nc();}
        return s*f;
    }
    void link1(int u,int v){e1[++tot1]=(E){v,h1[u]};h1[u]=tot1;}
    void link2(int u,int v){e2[++tot2]=(E){v,h2[u]};h2[u]=tot2;}
    void chkmin(int &x,int y){if (y<x) x=y;}
    void init(){
        mem(h1,0);mem(h2,0);mem(dfn,0);mem(low,0);mem(brige,0);
        tot1=tot2=1;
        tim=tp=0;
    }
    void tarjan(int x,int pre){
        dfn[x]=low[x]=++tim;
        for (int i=h1[x];i;i=e1[i].nxt){
            int y=e1[i].to;
            if (!dfn[y]){
                tarjan(y,i);
                chkmin(low[x],low[y]);
                if (low[y]>dfn[x]) brige[i]=brige[i^1]=1;
            }
            else if (i!=(pre^1)) chkmin(low[x],dfn[y]);
        }
    }
    void dfs(int x,int edcc){
        belong[x]=edcc;vis[x]=1;
        for (int i=h1[x],y;i;i=e1[i].nxt){
            if (vis[y=e1[i].to]||brige[i]) continue;
            dfs(y,edcc);
        }
    }
    void dfs1(int x,int len,int pre){
        if (len>mx) mx=len,pos=x;
        for (int i=h2[x],y;i;i=e2[i].nxt){
            if ((y=e2[i].to)==pre) continue;
            dfs1(y,len+1,x);
        }
    }
    int main(){
        freopen("rebuild.in","r",stdin);
        freopen("rebuild.out","w",stdout);
        while (1)
        {
            n=read();m=read();
            if (!n&&!m) break;
            init();
            for (int i=1,u,v;i<=m;i++){
                u=read();v=read();link1(u,v);link1(v,u);
            }
            tarjan(1,-1);
            mem(vis,0);
            int cnt=0;
            for (int i=1;i<=n;i++) if (!vis[i]) dfs(i,++cnt);
            for (int x=1;x<=n;x++)
                for (int i=h1[x];i;i=e1[i].nxt){
                    int y=e1[i].to;
                    if (belong[x]==belong[y]) continue;
                    link2(belong[x],belong[y]);
                }
            mx=0;
            dfs1(1,1,-1);
            mx=0;
            dfs1(pos,1,-1);
            printf("%d
    ",cnt-mx);
        }
        return 0;
    }
  • 相关阅读:
    MAC SAP for JAVA配置
    工艺路线查询
    工单批量关闭
    BOM批量查询
    SE11/SE16N修改表数据
    PI/PO Token配置
    标准IDOC同步物料
    SAP采购订单入库后不允许修改单价增强
    Sap Hana 关于BP的一些理解
    Sap MM 定义物料号码范围
  • 原文地址:https://www.cnblogs.com/xxzh/p/9805374.html
Copyright © 2011-2022 走看看