zoukankan      html  css  js  c++  java
  • hdu4612 Warm up[边双连通分量缩点+树的直径]

    给你一个连通图,你可以任意加一条边,最小化桥的数目。


    添加一条边,发现在边双内是不会减少桥的。只有在边双与边双之间加边才有效。于是,跑一遍边双并缩点,然后就变成一棵树,这样要加一条非树边,路径上的点(边双)就都变成一个大边双了,所以问题转化为求树上最长路径,跑直径即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #define mst(x) memset(x,0,sizeof x)
     8 #define dbg(x) cerr << #x << " = " << x <<endl
     9 #define dbg2(x,y) cerr<< #x <<" = "<< x <<"  "<< #y <<" = "<< y <<endl
    10 using namespace std;
    11 typedef long long ll;
    12 typedef double db;
    13 typedef pair<int,int> pii;
    14 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    15 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    16 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    17 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    18 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    19 template<typename T>inline T read(T&x){
    20     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    21     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    22 }
    23 const int N=2e5+7,M=1e6+7;
    24 struct thxorz{int to,nxt;}G1[M<<1],G2[N<<1];
    25 int Head1[N],Head2[N],tot1,tot2;
    26 int n,m;
    27 inline void Addedge(int x,int y){
    28     G1[++tot1].to=y,G1[tot1].nxt=Head1[x],Head1[x]=tot1;
    29     G1[++tot1].to=x,G1[tot1].nxt=Head1[y],Head1[y]=tot1;
    30 }
    31 inline void Addtedge(int x,int y){
    32     G2[++tot2].to=y,G2[tot2].nxt=Head2[x],Head2[x]=tot2;
    33     G2[++tot2].to=x,G2[tot2].nxt=Head2[y],Head2[y]=tot2;
    34 }
    35 #define y G1[j].to
    36 int dfn[N],low[N],cut[M<<1],cnt;
    37 void tarjan(int x,int i){
    38     dfn[x]=low[x]=++cnt;
    39     for(register int j=Head1[x];j;j=G1[j].nxt)if(j^(i^1)){
    40         if(!dfn[y]){
    41             tarjan(y,j);MIN(low[x],low[y]);
    42             if(low[y]>dfn[x])cut[j]=cut[j^1]=1;
    43         }
    44         else MIN(low[x],dfn[y]);
    45     }
    46 }
    47 int bel[N],dcc;
    48 void dfs(int x){
    49     bel[x]=dcc;
    50     for(register int j=Head1[x];j;j=G1[j].nxt)if(!bel[y]&&!cut[j])dfs(y);
    51 }
    52 #undef y
    53 #define y G2[j].to
    54 int dep,pt;
    55 void tree_dfs(int x,int fa,int d){
    56     if(MAX(dep,d))pt=x;
    57     for(register int j=Head2[x];j;j=G2[j].nxt)if(y^fa)tree_dfs(y,x,d+1);
    58 }
    59 #undef y
    60 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    61     while(read(n),read(m),n||m){
    62         tot1=1;dcc=tot2=cnt=dcc=0;mst(Head1),mst(Head2),mst(dfn),mst(low),mst(cut),mst(bel);
    63         for(register int i=1,x,y;i<=m;++i)read(x),read(y),Addedge(x,y);
    64         for(register int i=1;i<=n;++i)if(!dfn[i])tarjan(i,0);
    65         for(register int i=1;i<=n;++i)if(!bel[i])++dcc,dfs(i);
    66         for(register int t=2,u,v;t<=tot1;t+=2){
    67             u=G1[t].to,v=G1[t^1].to;
    68             if(bel[u]^bel[v])Addtedge(bel[u],bel[v]);//dbg2(bel[u],bel[v]);
    69         }
    70         dep=0,tree_dfs(1,0,1);dep=0,tree_dfs(pt,0,1);
    71         printf("%d
    ",dcc-dep);
    72     }
    73     return 0;
    74 }
    View Code

    总结:和桥有关的可以首先考虑缩点建树,因为树有很好的性质,并且树边都是有桥连接起来的,同一个边双方便处理。

  • 相关阅读:
    WebService安全 文件夹 目录安全性 身份验证与访问控制
    爱情故事[转载自:学狼网]
    未来中国最受宠的人才
    [引]SQL Server : 系统存储过程
    VS 安装项目 :通过文本框得到用户输入 以及 安装后运行某程序(如打开C:\\a.html)
    人人都能成为百万富翁
    成功原来这样简单
    精典谚语
    利用WinForm 更好的实现Web安装程序的更多功能
    升级安装包的制作
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11713845.html
Copyright © 2011-2022 走看看