[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;
10     void push(int x){v.push_back(x);}
11     void pop(){v.pop_back();}
12     int size(){return v.size();}
13     bool empty(){return v.empty();}
14     int top(){return v[v.size()-1];}
15 }s;
16
17 const int Maxn = 5010;
18
19 vector<int> g[Maxn],scc[Maxn];
20 int dfn[Maxn],low[Maxn],inscc[Maxn],ins[Maxn];
21 int inv[Maxn];
22 int n,m,cntv,cntscc,cnt;
23
24 void tarjan(int x,int fa){
25     low[x] = dfn[x] = ++cntv,ins[x] = 1;
26     s.push(x);int cntf = 0;
27     for(int i = 0;i < g[x].size();i++){
28         int u = g[x][i];
29         if(u == fa&&!cntf){cntf++;continue;}
30         if(!dfn[u])tarjan(u,x),low[x] = min(low[x],low[u]);
31         else low[x] = min(low[x],dfn[u]);
32     }
33     if(dfn[x] == low[x]){
34         int y = -1;cntscc++;
35         while(!s.empty()&&y^x){
36             y = s.top();s.pop();
37             ins[y] = 0,inscc[y] = cntscc;
38             scc[cntscc].push_back(y);
39         }
40     }
41 }
42
43 int main(){
44     scanf("%d%d",&n,&m);
45     for(int i = 1;i <= m;i++){
46         int u,v;
47         scanf("%d%d",&u,&v);
48         g[u].push_back(v);
49         g[v].push_back(u);
50     }
51     tarjan(1,-1);
52     for(int i = 1;i <= n;i++)
53         for(int j = 0;j < g[i].size();j++)
54             if(inscc[i]^inscc[g[i][j]])inv[inscc[g[i][j]]]++;
55     for(int i = 1;i <= cntscc;i++)if(inv[i] == 1)cnt++;
56     cout << (cnt+1)/2;
57 return 0;
58 }

原文地址:https://www.cnblogs.com/Wangsheng5/p/11782488.html

时间: 2024-09-28 01:31:02

[USACO06JAN]冗余路径Redundant Paths 无向图tarjan缩点的相关文章

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 [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

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

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

洛谷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 e-DCC缩点

冗余路径 Redundant Paths 题目传送 sol: 如果两点间存在至少两条不重复的路径,这说明他们两点在同一个边双连通分量(不存在割边). 那么可以进行e-DCC的缩点,得到一棵树. 对于这棵树广泛意义上的叶子节点(度数为1)而言,都还至少需要一条边连向他. 那么可以贪心的一次连两个叶子节点,答案显然就是\(cnt+1>>1\). #include<bits/stdc++.h> #define IL inline #define RG register #define D

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

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

冗余路径Redundant Paths

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

POJ 3177 Redundant Paths(Tarjan)

题目链接 题意 : 一个无向连通图,最少添加几条边使其成为一个边连通分量 . 思路 :先用Tarjan缩点,缩点之后的图一定是一棵树,边连通度为1.然后找到所有叶子节点,即度数为1的节点的个数leaf,最后要添加的边的条数就是(leaf+1)/2 : 1 // 3177 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 7 using

POJ 3177 Redundant Paths 无向图边双联通基础题

题意: 给一个无向图,保证任意两个点之间有两条完全不相同的路径 求至少加多少边才能实现 题解: 得先学会一波tarjan无向图 桥的定义是:删除这条边之后该图不联通 一条无向边(u,v)是桥,当且仅当(u,v)为树枝边,且满足 DFN(u)<Low(v).(因为 v 想要到达 u 的父亲必须经过(u,v)这条边,所以删去这条边,图不连通) 先用Tarjan无向图缩边双联通分量,这样原图就构成了一颗树, 对于树的叶子节点来说,显然他们需要连边,可以证明的是,我们连至多(叶子节点个数+1)/2的边就