poj-3177(并查集+双联通分量+Tarjan算法)

题目链接:传送门

思路:

题目要将使每一对草场之间都有至少两条相互分离的路径,所以转化为(一个有桥的连通图至少加几条边才能变为双联通图?)

先将桥删除,然后原图变为多个连通块,每一个连通块就是一个边双联通分量,将双联通子图收缩为一个顶点,再把桥边加回来,边连通度为1,

顺便统计度为1的节点的个数,即叶节点的个数即为cnt,所以至少在树上添加(cnt+1)/2条边。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 10010;
struct Edge{
    int u,v;
};
Edge tmp;
vector <Edge> ee;
int num[maxn],vis[maxn],low[maxn],fa[maxn],tog[maxn],m,n,tim;
vector <int> vc[maxn];
void Init()
{
    memset(vis,0,sizeof(vis));
    memset(num,0,sizeof(num));
    memset(low,0,sizeof(low));
    memset(fa,0,sizeof(fa));
    memset(tog,0,sizeof(tog));
    ee.clear();
    for(int i=0;i<maxn;i++) vc[i].clear();
    tim=1;
}
int MIN(int x,int y)
{
    return x<y?x:y;
}
int f(int x)
{
    if(fa[x]==0) return x;
    else return fa[x]=f(fa[x]);
}
void Tarjan(int v,int pre)
{
    int i,w;
    vis[v]=1;
    low[v]=num[v]=tim++;
    for(i=0;i<vc[v].size();i++){
        w=vc[v][i];
        if(!vis[w]){
            Tarjan(w,v);
            low[v]=MIN(low[v],low[w]);
            if(low[w]>num[v]){
                tmp.u=v;tmp.v=w;
                ee.push_back(tmp);
            }
            else{
                int t1=f(v);
                int t2=f(w);
                if(t1!=t2) fa[t2]=t1;
            }
        }
        else if(pre!=w) low[v]=MIN(low[v],num[w]);
    }
}
int main(void)
{
    int i,j,x,y;
    while(~scanf("%d%d",&n,&m)){
        Init();
        for(i=0;i<m;i++){
            scanf("%d%d",&x,&y);
            vc[x].push_back(y);
            vc[y].push_back(x);
        }
        Tarjan(1,-1);
        for(i=0;i<ee.size();i++){
            int t1=f(ee[i].u);
            int t2=f(ee[i].v);
            tog[t1]++;tog[t2]++;
        }
        int cnt=0;
        for(i=1;i<=n;i++)
        if(tog[i]==1) cnt++;
        cnt=(cnt+1)/2;
        printf("%d\n",cnt);
    }
    return 0;
} 

原文地址:https://www.cnblogs.com/2018zxy/p/10357599.html

时间: 2024-11-10 05:32:49

poj-3177(并查集+双联通分量+Tarjan算法)的相关文章

POJ 3177 Redundant Paths(边双联通图)

Description In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1..F) to another field, Bessie and the rest of the herd are forced to cross near the Tree of Rotten Apples. The cows are now tired of often being forc

HDU 4738 Caocao&#39;s Bridges(双联通分量+并查集)

大意:有n座岛和m条桥,每条桥上有w个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥,使得这n座岛不连通,求最少要派多少人去. 思路:我们就是要缩点后直接求桥上人的最少数量.(PS:1.注意图如果不联通直接输出0.2.如果图中的桥上人为0,个那么要让一个人去.3.重边的问题.这里可以忽略) #include<map> #include<queue> #include<cmath> #include<cstdio> #include<stac

poj3694 network(边双联通分量+lca+并查集)

题    目    传    送    们    在    这 题目大意 有一个由n个点和m条边组成的无向联通图. 现在有Q个操作,每次操作可以在点x,y之间连一条边. 问你每次操作后有多少个多少个桥(即删掉后就会使图不联通的边). 解题思路 根据边双联通的定义,我们知道将边双联通分量缩点后的图,其中的边即为桥. 我们将这个图缩点,就变成了一棵树. 而每次在两个不同的边双联通分量x,y之间加边后,就出现了一个包含x,y的环,其中原先这颗树上x,y的树上最短路径就不在是边. 所以对于每个x,y,我

【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)

[POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 11661   Accepted: 3824 Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, an

POJ 1515 双联通分量

点击打开链接 题意:给一个联通的无向图,然后问你将其中的边变为有向的,加边使其变成有向的联通图 思路:若无向图有双联通分量,那么这个分量里的元素可以变成有向图的强联通,这应该很好看出来,然后需要加的边是什么呢,就是这个图上的桥呗,是桥的话变成有向的就要加一条边,然后剩下的无向图的双联通分量可以用dfs搜一下,边搜边输出就可以了,将桥记录下来遇到桥的时候特殊处理一下,然后双联通分量里的边每一条只能走一次,将走得边和反向边标记一下就行了  PS:vector写这样反向边的真是麻烦 #include

双联通分量与二分图

我这是耽搁了多长时间才把它整完哈哈哈哈哈: 双联通分量 在无向图中,如果无论删去哪条边都不能使得 u 和 v 不联通,则称 u 和 v 边双连通: 在无向图中,如果无论删去哪个点(非 u 和 v)都不能使得 u 和v 不联通,则称 u 和 v 点双连通. 割点:删去该点,图分裂为多个连通块. 割边:也叫"桥",删去该边,图分裂为多个连通块. 点双连通分量 类似地,定义$ d f n_u 和 low_u$. 如果 v 是 u 的子结点,并且 $low_v ≥ d f n_u $则点 u

hihocoder #1190 : 连通性&#183;四 点双联通分量

http://hihocoder.com/problemset/problem/1190?sid=1051696 先抄袭一下 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho从约翰家回到学校时,网络所的老师又找到了小Hi和小Ho. 老师告诉小Hi和小Ho:之前的分组出了点问题,当服务器(上次是连接)发生宕机的时候,在同一组的服务器有可能连接不上,所以他们希望重新进行一次分组.这一次老师希望对连接进行分组,并把一个组内的所有连接关联的服务器也视为这个组内

[HDOJ4738]Caocao&#39;s Bridges(双联通分量,割边,tarjan)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 给一张无向图,每一条边都有权值.找一条割边,使得删掉这条边双连通分量数量增加,求权值最小那条. 注意有重边,ACEveryDay里群巨给的意见是tarjan的时候记录当前点是从哪条边来的. 注意假如桥的权值是0的时候也得有一个人去炸…… 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7

UVA - 10765 Doves and bombs (双联通分量)

链接 :  http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34798 给N个点的无向图并且联通,问删除每次一个点之后还剩多少联通分量. 找割顶 如果删除的是割顶 联通分量就会增加,否则还是1(因为原图是联通图),删除割顶之后 联通块的数目 就要看该割顶在几个双联通分量里出现过. #pragma comment(linker, "/STACK:10240000,10240000") #include <a