【HDU 4738 Caocao's Bridges】BCC 找桥
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738
题意:给定一个n个节点m条边的无向图(可能不连通、有重边),每条边有一个权值。判断其连通性,若双连通,输出-1;若非连通,输出0;否则,输出权值最小的桥的权值。
思路:进行双连通域分解,记下连通块的个数和所有桥的情况,对应输出结果即可。
注意对重边的处理。这里我按照上一道题学到的姿势如法炮制:先把所有边按“字典序”排序(u, v, w),这样重边聚集在一起了,然后扫描一遍,发现重边即在结构体Edge中打重边标记;由于重边一定不是桥,因此选哪个的权值实际上无所谓。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define CLEAR(A, X) memset(A, X, sizeof(A))
#define REP(N) for(int i=0; i<(N); i++)
#define REPE(N) for(int i=1; i<=(N); i++)
#define FREAD(FN) freopen((FN), "r", stdin)
#define pb(a) push_back(a) using namespace std; const int MAX_N = ;
const int MAX_M = ;
const int INF = ;
int n, m; struct Edge
{
int v, next;
int w;
bool isBrg;
bool isDup;
}edges[MAX_M];
int numE;
int head[MAX_N];
int low[MAX_N], dfn[MAX_N], clock;
int inStack[MAX_N], S[MAX_N], topS;
int block, belong[MAX_N];
int numBrg;
int cnt;//连通块个数 void init(){
numE = ;
clock = block = topS = ;
numBrg = ;
CLEAR(low, );
CLEAR(dfn, );
CLEAR(head, -);
CLEAR(belong, );
CLEAR(inStack, );
} void addEdge(int u, int v, int w, bool isDup){
edges[numE].v = v;
edges[numE].w = w;
edges[numE].isBrg = ;
edges[numE].isDup = isDup;
edges[numE].next = head[u];
head[u] = numE++; //反向边
edges[numE].v = u;
edges[numE].w = w;
edges[numE].isBrg = ; //这里之前忘清零了,一直WA。。。
edges[numE].isDup = isDup;
edges[numE].next = head[v];
head[v] = numE++;
} void bcc(int u, int p, int isDup){
low[u] = dfn[u] = ++clock;
S[topS++] = u;
inStack[u] = ;
for(int i=head[u]; i != -; i = edges[i].next){
int v = edges[i].v;
if(v == p && (!isDup)) continue;
if(!dfn[v]){
bcc(v, u, edges[i].isDup);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u]){//bridge
numBrg++;
edges[i].isBrg = ;
edges[i^].isBrg = ;
}
}else if(inStack[v]){//backward
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u]){//new bcc
block++;
int t;
do{
t = S[--topS];
inStack[t] = ;
belong[t] = block;
}while(t != u);
}
} struct Node
{
int u, v, w;
Node(){}
Node(int uu, int vv, int ww):u(uu), v(vv), w(ww){}
}nodes[MAX_M];
bool cmp(Node a, Node b){
if(a.u == b.u){
if(a.v == b.v) return a.w < b.w;
return a.v < b.v;
}
return a.u < b.u;
}
bool same(Node a, Node b){
return a.u == b.u && a.v == b.v;
} int main()
{
FREAD("4738.txt");
while(~scanf("%d%d", &n, &m) && !(n== && m==)){
init();
REP(m){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
if(u > v) swap(u, v);//保持顺序
nodes[i] = Node(u, v, w);
}
sort(nodes, nodes+m, cmp);
int cur = , i = ;
int flagDup = ;
while(cur < m){
while(i < m && same(nodes[cur], nodes[i])){
flagDup = ;
i++;
}//重边一定不是桥,
if(flagDup) addEdge(nodes[cur].u, nodes[cur].v, nodes[cur].w, true);
else addEdge(nodes[cur].u, nodes[cur].v, nodes[cur].w, false);
flagDup = ;
cur = i++;
}
cnt = ;
REPE(n){
if(!dfn[i]){
bcc(i, , );
cnt++;
}
}
int ans = INF;
if(cnt > ) ans = ;//非连通
else if(cnt== && !numBrg) ans = -;//边双连通
else{//有桥
// REPE(n){
// for(int j=head[i]; j != -1; j = edges[j].next){
// int v = edges[j].v;
// if(belong[i] != belong[v])
// ans = min(ans, edges[j].w);
// }
// }
REPE(numE){
if(edges[i].isBrg)
ans = min(ans, edges[i].w);
}
if(ans == ) ans = ;//至少派一人
}
printf("%d\n", ans);
}
return ;
}
判桥用 edges[i].isBrg 或 belong[u] == belong[v]都可以,二者等价。
多组样例,我开始用第一种但忘记在addEdge中把isBrg清零了才会WA。
【HDU 4738 Caocao's Bridges】BCC 找桥的更多相关文章
- HDU 4738 Caocao's Bridges ——(找桥,求联通块)
题意:给你一个无向图,给你一个炸弹去炸掉一条边,使得整个图不再联通,你需要派人去安置炸弹,且派去的人至少要比这条边上的人多.问至少要派去多少个,如果没法完成,就输出-1. 分析:如果这个图是已经是多个 ...
- Hdu 4738 Caocao's Bridges (连通图+桥)
题目链接: Hdu 4738 Caocao's Bridges 题目描述: 有n个岛屿,m个桥,问是否可以去掉一个花费最小的桥,使得岛屿边的不连通? 解题思路: 去掉一个边使得岛屿不连通,那么去掉的这 ...
- hdu 4738 Caocao's Bridges (tarjan求桥)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:给一些点,用一些边把这些点相连,每一条边上有一个权值.现在要你破坏任意一个边(要付出相 ...
- HDU 4738 Caocao's Bridges(Tarjan求桥+重边判断)
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 4738——Caocao's Bridges——————【求割边/桥的最小权值】
Caocao's Bridges Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 4738 Caocao's Bridges 图--桥的判断模板
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU——4738 Caocao's Bridges
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 4738 Caocao's Bridges
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- 《Learn python the hard way》Exercise 48: Advanced User Input
这几天有点时间,想学点Python基础,今天看到了<learn python the hard way>的 Ex48,这篇文章主要记录一些工具的安装,以及scan 函数的实现. 首先与Ex ...
- 关于bootstrap--表单(按钮<button>效果、大小、禁用)
1.各种标签实现按钮效果: <button class="btn btn-default" type="button">button标签按钮< ...
- Hibernate的几种查询方式-HQL,QBC,QBE,离线查询,复合查询,分页查询
HQL查询方式 这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多.条件查询.分页查询.连接查询.嵌套查询,写起来与SQL语法基本一致,唯一不同的就是把表名换成了 ...
- (转)iOS7界面设计规范(7) - UI基础 - 交互性与反馈
现在只是周日下午,可怎样都觉得整个周末就这样即将过去了,不免沮丧.看了好多集小丸子了,又不免觉得现在其实是在放暑假,可以一天一天的窝在家里做任何事,任何事.再上一篇iOS7设计规范,然后本周末就到这里 ...
- Android 避免APP启动闪黑屏的解决办法(Theme和Style)
前几天Boss就反应说,机器每次启动程序都会闪一下黑屏,这个客户不接受.没办法,只能想想怎么解决,最后找到了下面的方法.闪黑屏的原因主要是我们启动Activity的时候,需要跑完onCreate和on ...
- windows服务器性能监控工具、方法及关键指标
原文:http://www.cnblogs.com/liulun/p/3543777.html 监控方法 推荐使用windows自带的“性能监视器”(老版本的windows叫性能计数器)来监控服务器的 ...
- ListVeiw新增记录及 滚动条移动到指定位置
C# 自带的ListView控件的滚动条移动到指定位置. lvwList为ListView控件 lvwList.EnsureVisible(lvwList.Items.Count - 1); 新增记录 ...
- HTML与CSS入门——第十一章 在网页中使用图像
知识点: 1.在网页上放置图像的方法 2.用文本描述图像的方法 3.指定图像高度和宽度的方法 4.对齐图像的方法 5.将图像转换为俩接的方法 6.使用背景图像的方法 7.使用图像映射的方法 11.1 ...
- CSS 盒子模型(转)
CSS中, Box Model叫盒子模型(或框模型),Box Model规定了元素框处理元素内容(element content).内边距(padding).边框(border) 和 外边距(marg ...
- Android入门3:从Toolbar到Material Design
在Android5.0(API 21)之后,Toolbar被Google推广,逐渐走入大家视野.具体关于Actionbar和Toolbar的对比就不多啰嗦了,跟着潮流走是没错的.下面先上张简单的效果图 ...