poj 3177 Redundant Paths 边双连通分量+缩点

题意:给定n个点m条边。要使任意两个点可以通过两条严格不同的路径到达。即边不能重复,点可以重复。求需要添加的最小边数


题目就是要求使这个图成为边双连通分量所需添加的最小边数。

我的做法:

将边双连通分量相关的点缩点。然后求出度为1的个数=num。答案就是(num+1)/2或者说是num/2+num%2

理由:度为1的肯定是叶子节点或者根节点。将叶子节点两两配对。如果是奇数的话就任意与一个节点配对成边即可。

我在做边双连通分量缩点的过程异常麻烦。

首先我求出桥,然后删掉这些桥。将连通块缩点(这些连通块是边双连通分量)。然后再计算度数。。写的很多。感觉很麻烦。肯定有更简短的代码。。

---------2014/7/11 在下面还有一个代码 修改过后的。。写法比前面这个简便多了。

//author: CHC
//First Edit Time:	2014-07-11 10:04
//Last Edit Time:	2014-07-11 11:53
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define MAXN 5010
vector  e[MAXN];
vector  e1[MAXN];
vector  e2[MAXN];
int dfn[MAXN],low[MAXN],pre[MAXN],n,m;
int times=0,tot=0;
int du[MAXN];
void tarjan_3(int u){
    dfn[u]=low[u]=++times;
    for(int i=0;i<(int)e[u].size();i++){
        int v=e[u][i];
        if(!dfn[v]){
            pre[v]=u;
            tarjan_3(v);
            low[u]=min(low[u],low[v]);
        }
        else if(pre[u]!=v){
            low[u]=min(low[u],dfn[v]);
        }
    }
}
int vis[MAXN],tots;
void bfs(int u){
    vis[u]=++tots;
    queue  q;
    q.push(u);
    while(!q.empty()){
        int now=q.front();
        q.pop();
        for(int i=0;i<(int)e2[now].size();i++){
            int next=e2[now][i];
            if(vis[next])continue;
            vis[next]=vis[now];
            q.push(next);
        }
    }
}
bool check(int u,int v){
    if(e1[u].empty())return true;
    for(int i=0;i<(int)e1[u].size();i++){
        int v1=e1[u][i];
        if(v1==v)return false;
    }
    return true;
}
char has[MAXN];
void bfs1(int x){
    queue  q;
    q.push(x);
    has[x]=1;
    while(!q.empty()){
        int now=q.front();
        q.pop();
        for(int i=0;i<(int)e1[now].size();i++){
            int next=e1[now][i];
            if(has[next])continue;
            has[next]=1;
            ++du[now];
            ++du[next];
            q.push(next);
        }
    }
}
void solve(){
    tots=times=tot=0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(pre,0,sizeof(pre));
    for(int i=1;i<=n;i++)
        if(!dfn[i]) tarjan_3(i);
    //qiao
    for(int i=1;i<=n;i++){
        if(pre[i]>0&&dfn[pre[i]]%d\n",vis[i],vis[v]);
        }
    }
    memset(has,0,sizeof(has));
    for(int i=1;i<=tots;i++)
        if(!has[i])bfs1(i);
    int cnt=0;
    for(int i=1;i<=tots;i++){
        //printf("%d: %d\n",i,du[i]);
        if(du[i]==1)++cnt;
    }
    //printf("tots:%d\n",tots);
    //printf("cnt:%d\n",cnt);
    printf("%d\n",(cnt+1)/2);
    return ;
}

int main()
{
    //freopen("out.txt","r",stdin);
    //freopen("out-2.txt","w",stdout);
    while(~scanf("%d%d",&n,&m)){
        for(int i=0;i

//author: CHC
//First Edit Time:	2014-07-11 15:40
//Last Edit Time:	2014-07-11 16:26
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define MAXN 5010
struct Edge
{
    int to,next;
    bool vis,bge;
}edge[MAXN*2];
int dfn[MAXN],low[MAXN],pre[MAXN];
int sta[MAXN],bleg[MAXN];
int times,n,m,top;
int tot,head[MAXN];
void Add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    edge[tot].vis=false;
    edge[tot].bge=false;
    head[u]=tot++;
}
void tarjan_3(int u){
    dfn[u]=low[u]=++times;
    sta[++top]=u;
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(edge[i].vis)continue;
        edge[i].vis=edge[i^1].vis=true;
        if(!dfn[v]){
            pre[v]=u;
            tarjan_3(v);
            low[u]=min(low[u],low[v]);
        }
        else if(!bleg[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        bleg[0]++;
        do{
            bleg[sta[top]]=bleg[0];
        }while(sta[top--]!=u);
        bleg[u]=bleg[0];
    }
}
int du[MAXN];
void solve(){
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(pre,0,sizeof(pre));
    memset(bleg,0,sizeof(bleg));
    memset(du,0,sizeof(du));
    top=times=0;
    for(int i=1;i<=n;i++)
        if(!dfn[i]){
            tarjan_3(i);
        }
    for(int i=0;i




你可能感兴趣的:(ACM图论,强连通,桥,割点,点双连通,边双连通)