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

给一个图,问加多少条边可以干掉所有的桥。

先找环,然后缩点。标记对应环的度,接着找桥。写几个例子就能知道要添加的边数是桥的个数/2取上整。

这题和3177不一样的地方在于,这个题考虑重边,而我的代码本身,饿哦考虑重边的。

考虑重边:

找出桥,然后缩点。计算缩点后度为1的连通块个数。

 /*
━━━━━┒ギリギリ♂ eye!
┓┏┓┏┓┃キリキリ♂ mind!
┛┗┛┗┛┃\○/
┓┏┓┏┓┃ /
┛┗┛┗┛┃ノ)
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┃┃┃┃┃┃
┻┻┻┻┻┻
*/
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
#define fr first
#define sc second
#define cl clear
#define BUG puts("here!!!")
#define W(a) while(a--)
#define pb(a) push_back(a)
#define Rint(a) scanf("%d", &a)
#define Rll(a) scanf("%lld", &a)
#define Rs(a) scanf("%s", a)
#define Cin(a) cin >> a
#define FRead() freopen("in", "r", stdin)
#define FWrite() freopen("out", "w", stdout)
#define Rep(i, len) for(int i = 0; i < (len); i++)
#define For(i, a, len) for(int i = (a); i < (len); i++)
#define Cls(a) memset((a), 0, sizeof(a))
#define Clr(a, x) memset((a), (x), sizeof(a))
#define Full(a) memset((a), 0x7f7f, sizeof(a))
#define lp p << 1
#define rp p << 1 | 1
#define pi 3.14159265359
#define RT return
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<string, int> psi;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef vector<vl> vvl;
typedef vector<bool> vb; typedef struct Edge {
int v;
bool cut;
Edge() {}
Edge(int vv) : v(vv) { cut = ; }
}Edge; const int maxn = ;
const int maxm = ;
int n, m;
int dig[maxn];
int dfn[maxn], low[maxn], idx;
vector<Edge> G[maxn];
bool vis[maxn];
int st[maxn], top;
int belong[maxn], bcnt; void tarjan(int u, int p) {
int v;
low[u] = dfn[u] = ++idx;
vis[u] = ;
st[top++] = u;
Rep(i, G[u].size()) {
v = G[u][i].v;
if(v == p) continue;
if(!dfn[v]) {
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u]) {
G[u][i].cut = ;
Rep(j, G[v].size()) {
if(G[v][j].v== u) {
G[v][j].cut = ;
break;
}
}
}
}
else if(vis[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u]) {
bcnt++;
do {
v = st[--top];
vis[v] = ;
belong[v] = bcnt;
} while(v != u);
}
} int main() {
// FRead();
int u, v;
while(~Rint(n) && ~Rint(m)) {
Rep(i, n+) G[i].cl();
Cls(vis); Cls(dig); Cls(dfn); Cls(low);
top = ; idx = ; bcnt = ;
Rep(i, m) {
Rint(u); Rint(v);
G[u].pb(Edge(v)); G[v].pb(Edge(u));
}
tarjan(, );
int ret = ;
For(u, , n+) {
Rep(i, G[u].size()) {
if(G[u][i].cut) {
dig[belong[u]]++;
}
}
}
For(i, , bcnt+) {
if(dig[i] == ) ret++;
}
printf("%d\n", (ret+)>>);
}
RT ;
}

不考虑重边:

 /*
━━━━━┒ギリギリ♂ eye!
┓┏┓┏┓┃キリキリ♂ mind!
┛┗┛┗┛┃\○/
┓┏┓┏┓┃ /
┛┗┛┗┛┃ノ)
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┃┃┃┃┃┃
┻┻┻┻┻┻
*/
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
#define fr first
#define sc second
#define cl clear
#define BUG puts("here!!!")
#define W(a) while(a--)
#define pb(a) push_back(a)
#define Rint(a) scanf("%d", &a)
#define Rll(a) scanf("%lld", &a)
#define Rs(a) scanf("%s", a)
#define Cin(a) cin >> a
#define FRead() freopen("in", "r", stdin)
#define FWrite() freopen("out", "w", stdout)
#define Rep(i, len) for(int i = 0; i < (len); i++)
#define For(i, a, len) for(int i = (a); i < (len); i++)
#define Cls(a) memset((a), 0, sizeof(a))
#define Clr(a, x) memset((a), (x), sizeof(a))
#define Full(a) memset((a), 0x7f7f, sizeof(a))
#define lp p << 1
#define rp p << 1 | 1
#define pi 3.14159265359
#define RT return
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<string, int> psi;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef vector<vl> vvl;
typedef vector<bool> vb; const int maxn = ;
const int maxm = ;
int n, m;
int dig[maxn];
int pre[maxn], dfn[maxn], low[maxn];
vector<int> G[maxn];
bool vis[maxn]; void dfs(int u, int p) {
vis[u] = ;
pre[u] = p;
dfn[u] = low[u] = u;
Rep(i, G[u].size()) {
int v = G[u][i];
if(!vis[v]) dfs(v, u);
else if(v != p) low[u] = min(low[u], dfn[v]);
}
} void update(int u) {
int d = low[u];
while(u != d && u != ) {
low[u] = d;
u = pre[u];
}
} int main() {
// FRead();
int u, v;
while(~Rint(n) && ~Rint(m)) {
Rep(i, n+) G[i].cl();
Cls(vis); Cls(dig); Cls(dfn); Cls(low); Cls(pre);
Rep(i, m) {
Rint(u); Rint(v);
G[u].pb(v); G[v].pb(u);
}
For(i, , n+) if(!vis[i]) dfs(i, );
For(i, , n+) if(dfn[i] != low[i]) update(i);
For(u, , n+) {
Rep(i, G[u].size()) {
int v = G[u][i];
if(low[u] != low[v]) {
dig[low[u]]++; dig[low[v]]++;
}
}
}
int ret = ;
For(i, , n+) dig[i] /= ;
For(i, , n+) if(low[i] == i && dig[low[i]] == ) ret++;
printf("%d\n", ret % == ? ret / : ret / + );
}
RT ;
}

[POJ3352]Road Construction(缩点,割边,桥,环)的更多相关文章

  1. [POJ3352]Road Construction

    [POJ3352]Road Construction 试题描述 It's almost summer time, and that means that it's almost summer cons ...

  2. POJ3352 Road Construction 双连通分量+缩点

    Road Construction Description It's almost summer time, and that means that it's almost summer constr ...

  3. POJ-3352 Road Construction,tarjan缩点求边双连通!

    Road Construction 本来不想做这个题,下午总结的时候发现自己花了一周的时间学连通图却连什么是边双连通不清楚,于是百度了一下相关内容,原来就是一个点到另一个至少有两条不同的路. 题意:给 ...

  4. POJ3352 Road Construction (双连通分量)

    Road Construction Time Limit:2000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Sub ...

  5. POJ3352 Road Construction(边双连通分量)

                                                                                                         ...

  6. POJ3352 Road Construction Tarjan+边双连通

    题目链接:http://poj.org/problem?id=3352 题目要求求出无向图中最少需要多少边能够使得该图边双连通. 在图G中,如果任意两个点之间有两条边不重复的路径,称为“边双连通”,去 ...

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

    题意:有n个点,m条路,问你最少加几条边,让整个图变成边双连通分量. 思路:缩点后变成一颗树,最少加边 = (度为1的点 + 1)/ 2.3177有重边,如果出现重边,用并查集合并两个端点所在的缩点后 ...

  8. 边双联通问题求解(构造边双连通图)POJ3352(Road Construction)

    题目链接:传送门 题目大意:给你一副无向图,问至少加多少条边使图成为边双联通图 题目思路:tarjan算法加缩点,缩点后求出度数为1的叶子节点个数,需要加边数为(leaf+1)/2 #include ...

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

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 503 ...

随机推荐

  1. mysql查询差集

    select A.* from A left join B using(name,addr,age) where B.name is NULL; select A.* from A left join ...

  2. cocos2d下,优秀骨骼spine的换装思路

    语文老师说,文章要有个好开头!!! 最近正在引入spine骨骼代替dragon bone骨骼,既然要替代,那么原先在dragon bone上的一些额外需求,不管dragon bone上能不能实现,都应 ...

  3. js获取对象、数组的实际长度,元素实际个数

    /*获取对象.数组的长度.元素个数 *@param obj 要计算长度的元素,可以为object.array.string */ function count(obj){ var objType = ...

  4. angular-file-upload API angular文件上传插件

    官方例子 : http://nervgh.github.io/pages/angular-file-upload/examples/simple/ ===Directives=== nvFileSel ...

  5. hdu 4901

    一个简单的dp,比赛的时候太坚信自己的小聪明没用二维数组一直WA到死: #include<cstdio> #include<cstring> #define maxn 1009 ...

  6. unity3d android互调

    unityPlayer = new AndroidJavaClass("com.xxx.xxx.MainActivity"); curActivity = unityPlayer. ...

  7. c# Invoke和BeginInvoke 区别

    原文:http://www.cnblogs.com/mashang/archive/2009/08/01/1536730.html Control.Invoke 方法 (Delegate) :在拥有此 ...

  8. sql server2012 动态端口

    我们查询  exec sp_readerrorlog 0, 1, "listening" 时可以看有端口监听,有1433 1434 53698等. 这时我们可以打看配置管理器,查看 ...

  9. [转载]Spring Java Based Configuration

    @Configuration & @Bean Annotations Annotating a class with the @Configuration indicates that the ...

  10. hdoj 1102 Constructing Roads

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1102 分析:看到这题给出的都是矩阵形式,就知道了可以用Prim算法求MST. #include <i ...