[POJ3177]Redundant Paths(双连通图,割边,桥,重边)

题目链接:http://poj.org/problem?id=3177

和上一题一样,只是有重边。

如何解决重边的问题?

1、  构造图G时把重边也考虑进来,然后在划分边双连通分量时先把桥删去,再划分,其中桥的一端的割点归入当前正在划分的边双连通分量。这个处理比较麻烦;

2、  在输入图G的边时,若出现重边,则不把重边放入图G,然后在划分边双连通分量时依然用Low划分。

  1 /*
  2 ━━━━━┒ギリギリ♂ eye!
  3 ┓┏┓┏┓┃キリキリ♂ mind!
  4 ┛┗┛┗┛┃\○/
  5 ┓┏┓┏┓┃ /
  6 ┛┗┛┗┛┃ノ)
  7 ┓┏┓┏┓┃
  8 ┛┗┛┗┛┃
  9 ┓┏┓┏┓┃
 10 ┛┗┛┗┛┃
 11 ┓┏┓┏┓┃
 12 ┛┗┛┗┛┃
 13 ┓┏┓┏┓┃
 14 ┃┃┃┃┃┃
 15 ┻┻┻┻┻┻
 16 */
 17 #include <algorithm>
 18 #include <iostream>
 19 #include <iomanip>
 20 #include <cstring>
 21 #include <climits>
 22 #include <complex>
 23 #include <fstream>
 24 #include <cassert>
 25 #include <cstdio>
 26 #include <bitset>
 27 #include <vector>
 28 #include <deque>
 29 #include <queue>
 30 #include <stack>
 31 #include <ctime>
 32 #include <set>
 33 #include <map>
 34 #include <cmath>
 35 using namespace std;
 36 #define fr first
 37 #define sc second
 38 #define cl clear
 39 #define BUG puts("here!!!")
 40 #define W(a) while(a--)
 41 #define pb(a) push_back(a)
 42 #define Rint(a) scanf("%d", &a)
 43 #define Rll(a) scanf("%lld", &a)
 44 #define Rs(a) scanf("%s", a)
 45 #define Cin(a) cin >> a
 46 #define FRead() freopen("in", "r", stdin)
 47 #define FWrite() freopen("out", "w", stdout)
 48 #define Rep(i, len) for(int i = 0; i < (len); i++)
 49 #define For(i, a, len) for(int i = (a); i < (len); i++)
 50 #define Cls(a) memset((a), 0, sizeof(a))
 51 #define Clr(a, x) memset((a), (x), sizeof(a))
 52 #define Full(a) memset((a), 0x7f7f, sizeof(a))
 53 #define lp p << 1
 54 #define rp p << 1 | 1
 55 #define pi 3.14159265359
 56 #define RT return
 57 typedef long long LL;
 58 typedef long double LD;
 59 typedef unsigned long long ULL;
 60 typedef pair<int, int> pii;
 61 typedef pair<string, int> psi;
 62 typedef map<string, int> msi;
 63 typedef vector<int> vi;
 64 typedef vector<LL> vl;
 65 typedef vector<vl> vvl;
 66 typedef vector<bool> vb;
 67
 68 typedef struct Edge {
 69     int v;
 70     bool cut;
 71     Edge() {}
 72     Edge(int vv) : v(vv) { cut = 0; }
 73 }Edge;
 74
 75 const int maxn = 5500;
 76 const int maxm = 555011;
 77 int n, m;
 78 int dig[maxn];
 79 int dfn[maxn], low[maxn], idx;
 80 vector<Edge> G[maxn];
 81 bool vis[maxn];
 82 int st[maxn], top;
 83 int belong[maxn], bcnt;
 84
 85 void tarjan(int u, int p) {
 86     int v;
 87     low[u] = dfn[u] = ++idx;
 88     vis[u] = 1;
 89     st[top++] = u;
 90     Rep(i, G[u].size()) {
 91         v = G[u][i].v;
 92         if(v == p) continue;
 93         if(!dfn[v]) {
 94             tarjan(v, u);
 95             low[u] = min(low[u], low[v]);
 96             if(low[v] > dfn[u]) {
 97                 G[u][i].cut = 1;
 98                 Rep(j, G[v].size()) {
 99                     if(G[v][j].v== u) {
100                         G[v][j].cut = 1;
101                         break;
102                     }
103                 }
104             }
105         }
106         else if(vis[v]) low[u] = min(low[u], dfn[v]);
107     }
108     if(low[u] == dfn[u]) {
109         bcnt++;
110         do {
111             v = st[--top];
112             vis[v] = 0;
113             belong[v] = bcnt;
114         } while(v != u);
115     }
116 }
117
118 int main() {
119     FRead();
120     int u, v;
121     while(~Rint(n) && ~Rint(m)) {
122         Rep(i, n+50) G[i].cl();
123         Cls(vis); Cls(dig); Cls(dfn); Cls(low);
124         top = 0; idx = 0; bcnt = 0;
125         Rep(i, m) {
126             Rint(u); Rint(v);
127             G[u].pb(Edge(v)); G[v].pb(Edge(u));
128         }
129         tarjan(1, 0);
130         int ret = 0;
131         For(u, 1, n+1) {
132             printf("%d ", belong[u]);
133             Rep(i, G[u].size()) {
134                 if(G[u][i].cut) {
135                     dig[belong[u]]++;
136                 }
137             }
138         }
139         printf("\n");
140         For(i, 1, bcnt+1) {
141             if(dig[i] == 1) ret++;
142         }
143         printf("%d\n", (ret+1)>>1);
144     }
145     RT 0;
146 }
时间: 2024-10-08 01:19:30

[POJ3177]Redundant Paths(双连通图,割边,桥,重边)的相关文章

POJ3177 Redundant Paths 双连通分量

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

POJ3177 Redundant Paths (双联通缩点)

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

poj3177 Redundant Paths 边双连通分量

#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define eps 1e-

poj 3177 求至少添加多少条边可以成为边-双连通图(有重边)

[题意]:给出一张无向连通图,求添加多少条边可以成为边-双连通图 [思路]:同3352 一样,求出边-双连通分量,缩点就成了一棵树,求这棵树里的出度为1 的点num  结果是(num-1)/2; 但是!!  这里和3352 哟一点不一样就是这里有重边,当有重边的时候,不同low值的两点可能属于同一个边-双连通分量 所以在构图的时候要注意把重边去掉! 1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h>

【连通图|边双连通+缩点】POJ-3177 Redundant Paths

Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K       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 T

POJ3177:Redundant Paths(并查集+桥)

Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19316   Accepted: 8003 题目链接:http://poj.org/problem?id=3177 Description: In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1..F) to anot

poj 3177 Redundant Paths (双联通)

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

POJ3177 Redundant Paths【边双联通分量】【Tarjan】

题目链接: http://poj.org/problem?id=3177 题目大意: Bessie的农场有F块牧场,已知当前任意两个农场之间至少有一条路径相连(并不一定直接相连) 为了从某块牧场移动到另一块牧场,Bessie和她的伙伴经常需要经过腐烂的树林.奶牛们特别 反感经过不好走的路,于是Bessie决定在农场种再建几条路,使得在去某个地方时总能够有两 条完全独立的路可够选择.那么问题来了:F块牧场,R条路,问至少再修几条路就能使得农场 中任意两个牧场之间都有至少两条相互独立的路径. 思路:

poj3352 Road Construction &amp; poj3177 Redundant Paths (边双连通分量)题解

题意:有n个点,m条路,问你最少加几条边,让整个图变成边双连通分量. 思路:缩点后变成一颗树,最少加边 = (度为1的点 + 1)/ 2.3177有重边,如果出现重边,用并查集合并两个端点所在的缩点后的点. 代码: /*3352*/ #include<set> #include<map> #include<stack> #include<cmath> #include<queue> #include<vector> #include&