zoukankan      html  css  js  c++  java
  • poj3177 Redundant Paths

    题目大意:给一个连通图,求最少加多少边使它变成一个点联通分量。

    先找割边,然后把没有桥的点双连通分量缩成一个连通分量。

    这些连通分量按原来的关系连在一起就是一颗树。

    把树变成一个点双联图图需要加(叶节点数+1)/2个边。

    问题是怎么求点双连通分量。

    如果一个点的dfn=low,说明目前栈中的元素都需要弹出,成为一个点双连通分量。

    把他们记录到结构体里面就好了

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <stack>
    #define in(a) a=read()
    #define MAXN 10010
    #define REP(i,k,n)  for(int i=k;i<=n;i++)
    using namespace std;
    inline int read(){
        int x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar())
            if(ch=='-')
                f=-1;
        for(;isdigit(ch);ch=getchar())
            x=x*10+ch-'0';
        return x*f;
    }
    int n,m,ans;
    int total=0,head[MAXN],nxt[MAXN<<1],to[MAXN<<1];//ÁÚ½Ó±í 
    int ind,dfn[MAXN],low[MAXN],vis[MAXN<<1];//¸î±ß 
    int num,bel[MAXN];//Ëõµã 
    int du[MAXN];
    stack <int> S;
    inline void adl(int a,int b){
        total++;
        to[total]=b;
        nxt[total]=head[a];
        head[a]=total;
        return ;
    }
    inline void tarjan(int u){
        S.push(u);
        dfn[u]=low[u]=++ind;
        for(int e=head[u];e;e=nxt[e]){
            if(e%2 && vis[e+1])  continue;
            if(!(e%2) && vis[e-1])  continue; 
            if(vis[e])  continue;
            vis[e]=1;
            if(!dfn[to[e]]){
                tarjan(to[e]);
                low[u]=min(low[u],low[to[e]]);
            }
            else  low[u]=min(low[u],dfn[to[e]]);
        }
        if(low[u]==dfn[u]){
            num++;
            int v;
            do{
                v=S.top();
                bel[v]=num;
                S.pop();
            }while(u!=v);
        }
        return ;
    }
    int main(){
        in(n),in(m);
        int a,b;
        REP(i,1,m)  in(a),in(b),adl(a,b),adl(b,a);
        tarjan(1);
        REP(u,1,n)
            for(int e=head[u];e;e=nxt[e])
                if(bel[u]!=bel[to[e]])
                    du[bel[u]]++,du[bel[to[e]]]++;
        REP(i,1,num)  if((du[i]/2)==1)  ans++;
        cout<<(ans+1)/2;
        return 0;
    }
  • 相关阅读:
    Discuz中解决jquery 冲突的方法 绝对简单
    关于MySql has gone away问题的解决
    关于水晶报表的一些错误
    biweb后台添加上传下载功能
    ajax 异步插入图片到数据库(多图上传)
    ajax 异步插入图片到数据库(单图上传)
    使用ajax异步提交表单数据(史上最完整的版本)
    系统管理-软件管理
    系统管理-计划任务-系统日志
    Django-ondelete
  • 原文地址:https://www.cnblogs.com/jason2003/p/10224199.html
Copyright © 2011-2022 走看看