POJ 3352 Road Construction&& POJ 3177 Redundant Paths 双联通分量

大意:给定n点,和m条边的关系图中的一些边随时可能施工导致不能够通过,所以至少加多少条边才能够使得途中任意两条边联通?

思路:很明显只要图中的任意两点都是两条边来链接即可。那么我们可以先缩点构建新图,然后统计出度为1的点的个数ans,那么需要加的边数就是(ans+1)/2条;

(PS;因为建图是双向的图所以,在Tarjan缩点的时候就需要遇到临边便越过,并且判断是不是同一个联通分支用num比较!)

#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#include<stack>
#include<iostream>
#include<cstring>
#include<algorithm>
#define LL int
#define inf 0x3f3f3f3f
#define eps 1e-8
#include<vector>
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
using namespace std;
int n,m;
const int Ma = 1000005;

int head[Ma],dfn[Ma],num[Ma],du[Ma],stk[Ma],vis[Ma],low[Ma];
int cnt,top,time,css;
bool mp[5100][5100];
struct node{
    int to,next;
}q[Ma];

void bu(int a,int b){
    q[cnt].to = b;
    q[cnt].next = head[a];
    head[a] = cnt++;
}

void init(){
    time = 1;
    css = top = cnt = 0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(vis,0,sizeof(vis));
    memset(head,-1,sizeof(head));
    memset(num,0,sizeof(num));
    memset(du,0,sizeof(du));
    memset(mp,false,sizeof(mp));
}

void Tarjan(int u,int To){
    low[u] = dfn[u] = time++;
    vis[u] = 1;
    stk[top++] = u;
    for(int i = head[u]; ~i ; i = q[i].next){
        int v = q[i].to;
        if(i == (To^1)) continue;
        if(!vis[v]){
            Tarjan(v,i);
            low[u] = min(low[u],low[v]);
        }
        else
            low[u] = min(low[u],dfn[v]);

    }
    if(low[u] == dfn[u]){//找到极大联通分量
        css++;
        while(top > 0&&stk[top] != u){
            top --;
            vis[stk[top] ] = 2;
            num[stk[top] ] = css;
        }
    }

}

int main(){
    int k,i,j,a,b;
    while(~scanf("%d%d",&n,&m)){
        init();
        for(i = 0;i < m;++ i){
            scanf("%d%d",&a,&b);//////注意重边的问题!
            if(mp[a][b]){
                continue;
            }
            mp[a][b] = mp[b][a] = true;
            bu(a,b);
            bu(b,a);
        }
        Tarjan(1,-1);
        for(i = 1;i <= n;++ i)
            for(j = head[i]; ~j ;j = q[j].next)
                if( num[i] != num[q[j].to] )
                    du[num[i] ]++;
        int ans = 0;
        for(i = 1;i <= n;++ i)
            if(du[i] == 1)
                ans++;
        printf("%d\n",(ans+1)>>1);
    }
    return 0;
}
时间: 2024-10-09 15:22:01

POJ 3352 Road Construction&& POJ 3177 Redundant Paths 双联通分量的相关文章

POJ 3352 Road Construction POJ 3177 Redundant Paths(边双连通图 Tarjan+缩点)

POJ 3352 Road Construction POJ 3177 Redundant Paths(边双连通图 Tarjan+缩点) ACM 题目地址: POJ 3352 Road Construction POJ 3177 Redundant Paths 题意: 问要添加几条边才能使所给无向图图变成边双连通图. 分析: 边连通度:使无向图G不连通的最少删边数量为其边连通度. 边双连通图:边连通度大于1的无向图. 首先缩点,让图变成一个DAG. 现在问题转化为:在树中至少添加多少条边能使图变

POJ 3352 Road Construction 使得无向图边变双连通图

点击打开链接 Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8168   Accepted: 4106 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of

poj 3177 Redundant Paths (双联通)

/******************************************************* 题目:Redundant Paths (poj 2177) 链接:http://poj.org/problem?id=3177 算法:双联通+缩点 思路:先找出所有双联通分量,把这些分量缩成一个点 再找出所有度为一的点,用这些点数加一除2就可以了 ********************************************************/ #include<cs

Poj 3352 Road Construction &amp; Poj 3177 Redundant Paths(边双连通分量+缩点)

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9465   Accepted: 4699 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the ro

POJ 3177 Redundant Paths POJ 3352 Road Construction(双连通)

POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的,一份代码能交,给定一个连通无向图,问加几条边能使得图变成一个双连通图 思路:先求双连通,缩点后,计算入度为1的个数,然后(个数 + 1) / 2 就是答案(这题由于是只有一个连通块所以可以这么搞,如果有多个,就不能这样搞了) 代码: #include <cstdio> #include <cstring> #include <algorithm&

POJ 3352 Road Construction(图论-tarjan)

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8647   Accepted: 4318 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the ro

POJ - 3352 Road Construction(边双连通分支)

1.给定一个连通的无向图G,至少要添加几条边,才能使其变为双连通图. 2.POJ - 3177 Redundant Paths(边双连通分支)(模板)  与这道题一模一样.代码就改了下范围,其他都没动... 3. //边双连通分支 /* 去掉桥,其余的连通分支就是边双连通分支了.一个有桥的连通图要变成边双连通图的话, 把双连通子图收缩为一个点,形成一颗树.需要加的边为(leaf+1)/2(leaf为叶子结点的个数) POJ 3177 给定一个连通的无向图G,至少要添加几条边,才能使其变为双连通图

POJ 3352 Road Construction(无向连通图)

题目地址:POJ 3352 这题就是求最少加多少条边可以使得图为无向双连通图.方法是找度数为1的连通分量,可以只用low来找.然后根据公式(叶子结点数+1)/2即可得到答案.原因是在图中将每两个度数为1的都连起来,度数为2的显然已经可以形成双联通了,因为是无向边,只要加一条,就相当于加了两条有向边,很显然,结果数就是那个公式. 代码如下: #include <iostream> #include <cstdio> #include <string> #include &

poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&amp;&amp;缩点】

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 5031 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the r