题目链接: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 找桥的更多相关文章

  1. HDU 4738 Caocao's Bridges ——(找桥,求联通块)

    题意:给你一个无向图,给你一个炸弹去炸掉一条边,使得整个图不再联通,你需要派人去安置炸弹,且派去的人至少要比这条边上的人多.问至少要派去多少个,如果没法完成,就输出-1. 分析:如果这个图是已经是多个 ...

  2. Hdu 4738 Caocao's Bridges (连通图+桥)

    题目链接: Hdu 4738 Caocao's Bridges 题目描述: 有n个岛屿,m个桥,问是否可以去掉一个花费最小的桥,使得岛屿边的不连通? 解题思路: 去掉一个边使得岛屿不连通,那么去掉的这 ...

  3. hdu 4738 Caocao's Bridges (tarjan求桥)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:给一些点,用一些边把这些点相连,每一条边上有一个权值.现在要你破坏任意一个边(要付出相 ...

  4. HDU 4738 Caocao's Bridges(Tarjan求桥+重边判断)

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. HDU 4738——Caocao's Bridges——————【求割边/桥的最小权值】

     Caocao's Bridges Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  6. HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. hdu 4738 Caocao's Bridges 图--桥的判断模板

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  8. HDU——4738 Caocao's Bridges

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  9. HDU 4738 Caocao's Bridges

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

随机推荐

  1. 从有限状态机的角度去理解Knuth-Morris-Pratt Algorithm(又叫KMP算法)

    转载请加上:http://www.cnblogs.com/courtier/p/4273193.html 在开始讲这个文章前的唠叨话: 1:首先,在阅读此篇文章之前,你至少要了解过,什么是有限状态机, ...

  2. xm学习笔记

    1关于静态网页的制作 html主要负责页面的结构+css页面的美观+js与用户的交互. 2html 有标签体的标签: <p></p>  <span></spa ...

  3. poj 1742 Coins(dp之多重背包+多次优化)

    Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...

  4. Windows下模拟Linux开发

    1.背景 Linux环境下开发是大势所趋,也是开发者必须掌握的技能.然windows系统已深入人心,实在不想放弃windows下的成熟应用,因此可以在Windows上模拟一个Linux系统.这样就满足 ...

  5. 【转】WCF、WebAPI、WCFREST、WebService之间的区别

    在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下,你有很多的选择来构建一个HTTP Services.我分享一下我对 ...

  6. iphone真机开发流程之--证书申请

    一.申请 1.进入ios开发者中心 http://www.apple.com.cn/developer/ios/index.html 2.点击登录 输入用户名和密码(前提:已经有Apple ID,且花 ...

  7. Arcgis for js载入天地图

    综述:本节讲述的是用Arcgis for js载入天地图的切片资源. 天地图的切片地图能够通过esri.layers.TiledMapServiceLayer来载入.在此将之进行了一定的封装,例如以下 ...

  8. java.lang.OutOfMemoryError: Java heap space错误及处理办法

      以下是从网上找到的关于堆空间溢出的错误解决办法: java.lang.OutOfMemoryError: Java heap space ============================= ...

  9. java基础2

    //第一个程序 用super访问父类中被隐藏的成员变量和被重写的方法 package foxe; class superClass{ int x; superClass(){ x=4; System. ...

  10. C#图像处理(3):在图像上加条形码

    引入Aspose.BarCode用来生成条形码,方法如下: /// <summary> /// 生成条码 /// </summary> /// <param name=& ...