hdu 4612 求边连通分量+求树的直径

来源:互联网 发布:苹果ios7是什么软件 编辑:程序博客网 时间:2024/04/29 20:47

http://acm.hdu.edu.cn/showproblem.php?pid=4612
题意:
加一条边,使得桥的数量最少?
思路:
求边连通分量,缩点,然后变成一个树,树边都是桥,求树的直径。
树的直径就是最多减少的桥。
桥的数量最少就是原图中的桥的数量 - 树的直径。

要注意重边。

#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <map>using namespace std;typedef pair<int,int> pii;const int M_node = 200009, M_edge = 2000009;int low[M_node],dfn[M_node],belong[M_node],head[M_node];int dfs_clock,block,bridge,tot;int n,m,maxlen,s;bool instack[M_node];struct Node{    int u,v;}node[M_edge];struct edge{    int to,next;    bool cut;    bool mul;}edge[M_edge];vector<int> G[M_node];stack<int> st;void init(){    memset(head,-1,sizeof(head));    dfs_clock = block = bridge = tot = 0;}void add_edge(int u,int v,bool mul){    edge[tot].to = v;    edge[tot].next = head[u];    edge[tot].cut = false;    edge[tot].mul = mul;    head[u] = tot++;}void tarjan(int u,int fa,bool mul){    low[u] = dfn[u] = ++dfs_clock;    st.push(u);    instack[u] = true;    for(int i = head[u]; i != -1;i = edge[i].next)    {        int v = edge[i].to;        if(v == fa && !mul) continue; //如果不是重边才跳过        if(!dfn[v])        {            tarjan(v,u,edge[i].mul);            low[u] = min(low[v],low[u]);            if(low[v] > dfn[u])            {                bridge++;                edge[i].cut = true;                edge[i^1].cut = true;            }        }        else if(instack[u] && low[u] > dfn[v]) low[u] = dfn[v];    }    if(low[u] == dfn[u])    {        block++;        for(;;)        {            int v = st.top();            st.pop();            instack[v] = false;            belong[v] = block;            if(v == u) break;        }    }}void dfs(int u,int pre,int len){    if(maxlen < len)    {        s = u;        maxlen = len;    }    for(int i = 0; i < G[u].size();i++)    {        int v = G[u][i];        if(v == pre) continue;        dfs(v,u,len+1);    }}void solve(){    while(!st.empty()) st.pop();    memset(dfn,0,sizeof(dfn));    memset(instack,false,sizeof(instack));    tarjan(1,-1,false);    for(int i = 1;i <= block;i++) G[i].clear();    for(int i = 1;i <= n;i++)    {        for(int j = head[i];j != -1;j = edge[j].next)        {            if(edge[j].cut)            {                //printf("debug -- i = %d , belong[i] = %d , edge[j].to = %d , belong[edge[j].to] = %d\n",i,belong[i],edge[j].to,belong[edge[j].to]);                G[belong[i]].push_back(belong[edge[j].to]);            }        }    }    maxlen = -1;    dfs(1,-1,0);    maxlen = -1;    dfs(s,-1,0);    printf("%d\n",bridge - maxlen);}bool cmp(Node a,Node b){    if(a.u == b.u) return a.v < b.v;    return a.u < b.u;}int main(){    while(scanf("%d %d",&n,&m) == 2)    {        init();        if(n == 0 && m == 0) break;        for(int i = 0;i < m;i++)        {            int a,b;            scanf("%d %d",&a,&b);            if(a == b) continue;            if(a > b) swap(a,b);            node[i].u = a;            node[i].v = b;        }        sort(node,node+m,cmp);        for(int i = 0;i < m;i++)        {            if(i == 0 || (node[i].u != node[i-1].u || node[i].v != node[i-1].v))            {                if(i < m - 1 && node[i].u == node[i+1].u && node[i].v == node[i+1].v)                {                    add_edge(node[i].u,node[i].v,true);                    add_edge(node[i].v,node[i].u,true);                }                else                {                    add_edge(node[i].u,node[i].v,false);                    add_edge(node[i].v,node[i].u,false);                }            }        }        solve();    }    return 0;}
0 0
原创粉丝点击