冗余路径 Redundant Paths e-DCC缩点

冗余路径 Redundant Paths

题目传送

sol:

如果两点间存在至少两条不重复的路径,这说明他们两点在同一个边双连通分量(不存在割边)。

那么可以进行e-DCC的缩点,得到一棵树。

对于这棵树广泛意义上的叶子节点(度数为1)而言,都还至少需要一条边连向他。

那么可以贪心的一次连两个叶子节点,答案显然就是\(cnt+1>>1\)。

#include<bits/stdc++.h>
#define IL inline
#define RG register
#define DB double
#define LL long long
using namespace std;

const int N=5005;
const int M=1e4+5;

int n,m,tot,cnt,leaf,Time,head[N],bel[N],vis[N],low[N],dfn[N],bri[M<<1];

struct edge{int x,y;}s[M];
struct EDGE{int next,to;}e[M<<1];

IL int gi() {
    RG int x=0,p=1; RG char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') p=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
    return x*p;
}

IL void New() {
    tot=0;
    memset(&e,0,sizeof(e));
    memset(head,0,sizeof(head));
}

IL void make(int a,int b) {
    e[++tot]=(EDGE){head[a],b},head[a]=tot;
    e[++tot]=(EDGE){head[b],a},head[b]=tot;
}

void Tarjan(int x,int fx) {
    RG int i,y;
    dfn[x]=low[x]=++Time;
    for(i=head[x];i;i=e[i].next) {
        if(!dfn[y=e[i].to]) {
            Tarjan(y,x),low[x]=min(low[x],low[y]);
            if(low[y]>dfn[x]) bri[i]=bri[i^1]=1;
        }
        else if(y!=fx) low[x]=min(low[x],dfn[y]);
    }
}

void dfs(int x) {
    RG int i,y;
    bel[x]=cnt,vis[x]=1;
    for(i=head[x];i;i=e[i].next)
        if(!vis[y=e[i].to]&&!bri[i]) dfs(y);
}

void dfs2(int x,int fx) {
    RG int i,y,fl=0;
    for(i=head[x];i;i=e[i].next)
        if((y=e[i].to)!=fx) fl=1,dfs2(y,x);
    if(!fl) ++leaf;
}

int main()
{
    RG int i,b=0;
    n=gi(),m=gi(),tot=1;
    for(i=1;i<=m;++i)
        s[i].x=gi(),s[i].y=gi(),make(s[i].x,s[i].y);
    for(i=1,Tarjan(1,0);i<=n;++i)
        if(!vis[i]) ++cnt,dfs(i);
    if(cnt==1) return puts("0"),0;
    for(i=1,New();i<=m;++i)
        if(bel[s[i].x]!=bel[s[i].y]) make(bel[s[i].x],bel[s[i].y]);
    dfs2(1,0);
    for(i=head[1];i;i=e[i].next) ++b;
    if(b==1) ++leaf;
    printf("%d\n",leaf+1>>1);
    return 0;
}

原文地址:https://www.cnblogs.com/Bhllx/p/11258322.html

时间: 2024-10-09 21:42:23

冗余路径 Redundant Paths e-DCC缩点的相关文章

[USACO06JAN]冗余路径Redundant Paths 无向图tarjan缩点

如题,缩完点后数一下有几个入度为1的scc,+1再/2即可. 教训:加一个cntf处理重边!否则重边会被认为是同一条. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 struct stack{ 9 vector<int> v;

Luogu2860 [USACO06JAN]冗余路径Redundant Paths

\(\verb|Luogu2860 [USACO06JAN]冗余路径Redundant Paths|\) 给定一个连通无向图,求至少加多少条边才能使得原图变为边双连通分量 \(1\leq n\leq5000,\ n-1\leq m\leq10^4\) tarjan 边双无疑不用考虑,于是就可以边双缩点成一棵树 令现在要连的边为 \((u,\ v)\) ,点集 \(\{u->lca(u,\ v),\ v->lca(u,\ v)\}\) 将会变为一个新的点双,可以将他们看为一个新的点 可以贪心地连

luogu题解 P2860[USACO冗余路径Redundant Paths] 缩点+桥

题目链接 https://www.luogu.org/problemnew/show/P2860 https://www.lydsy.com/JudgeOnline/problem.php?id=1718 分析 首先这题目的意思就是让任意两点之间至少有两条没有重复道路的路径,很显然,如果这个图不存在桥,就一定满足上述条件. 于是我们就是要求使这个图不存在桥需要连接的最小边数 如果把桥从图中去掉,很显然剩余的联通块中任意两点之间至少有两条没有重复道路的路径(当然也可能不是联通块而是孤立的点),对答

[USACO06JAN]冗余路径Redundant Paths(缩点)

为了从F(1≤F≤5000)个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们已经厌倦了被迫走某一条路,所以她们想建一些新路,使每一对草场之间都会至少有两条相互分离的路径,这样她们就有多一些选择. 每对草场之间已经有至少一条路径.给出所有R(F-1≤R≤10000)条双向路的描述,每条路连接了两个不同的草场,请计算最少的新建道路的数量, 路径由若干道路首尾相连而成.两条路径相互分离,是指两条路径没有一条重合的道路.但是,两条分离的路径上可以有一些相同的草场.

LUOGU P2860 [USACO06JAN]冗余路径Redundant Paths (双联通,缩点)

传送门 解题思路 刚开始是找的桥,后来发现这样不对,因为一条链就可以被卡.后来想到应该缩点后找到度数为1 的点然后两两配对. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<set> using namespace std; const int MAXN = 5005; const int MAXM = 10005; inline i

洛谷P2860 [USACO06JAN]冗余路径Redundant Paths

题目描述 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 forced to t

冗余路径Redundant Paths

题意翻译 题目描述 在Byteotia有n个城镇. 一些城镇之间由无向边连接. 在城镇外没有十字路口,尽管可能有桥,隧道或者高架公路(反正不考虑这些).每两个城镇之间至多只有一条直接连接的道路.人们可以从任意一个城镇直接或间接到达另一个城镇. 每个城镇都有一个公民,他们被孤独所困扰.事实证明,每个公民都想拜访其他所有公民一次(在主人所在的城镇).所以,一共会有n*(n-1)次拜访. 不幸的是,一个程序员总罢工正在进行中,那些程序员迫切要求购买某个软件. 作为抗议行动,程序员们计划封锁一些城镇,阻

POJ3177 Redundant Paths (双联通缩点)

求对于给定一个连通图,加多少条边可以变成边双连通图. 一个有桥的连通图要变成边双连通图的话,把双连通子图收缩为一个点,形成一颗树.需要加的边为(leaf+1)/2 (leaf为叶子结点个数). 对于此题,有重边但重边不加入计算. 重边的话,要么在开始去掉,要么用桥来计算入度. 因为桥不属于任何一个边双连通分支,其余的边和每个顶点都属于且只属于一个边双连通分支.对于重边而言,只有一对边被标记为桥,而对于所有重边来言,belong[u]和belong[v]都是不一样的,那么如果用belong[u]!

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 for