您的位置:首页 > 其它

HDU 4514 湫湫系列故事——设计风景线 (并查集)

2013-03-23 18:46 281 查看
判断有没有环路,我个人认为还是并查集效率要高,而且复杂度要比dfs低,性价比很好

这道题的要求,第一判断是否有环,如果没有环,就输出最长的路径

我们可以想到一个无向图如果没有环的话,一定就是两种形态,一种是一棵树,另一种就是森林

那么要求最长路径的话,也就是要求树的半径

大致的思想明白了,就说一下细节吧

并查集的思想就是在图中找一个节点作为根,凡是和这点在一个连通分量里面的点,都插入到这个根上,是的前驱是这个根或者前前驱是这个根,由于并查集的维护,使得这儿数据结构很高效,具体的内容可以找书看。有一个重要的性质就是,如果发现了一条边的两个点的根是一个,说明加上这条边,图中就存在环了,画个图看看,就显而易见了。

详细见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N=100022;
int f
, num
;
int find( int x )
{
return ( f[x] == x ) ? x : f[x] = find(f[x]);
}
int main()
{
int n, m, t1, t2;
int u, v, w;
int ans;
bool fl;
while( scanf("%d%d",&n,&m) != EOF ) {
for(int i = 1; i <= n; i++ ) f[i] = i;
memset( num, 0, sizeof(num) );
fl = true;
ans = 0;
while( m-- ) {
scanf("%d%d%d", &u, &v, &w);
t1 = find( u ); //找父节点
t2 = find( v );
if( !fl ) continue;
if( t1 == t2 ) fl=false;
else {
f[t1] = t2; //将两连通分量连起来,也就是将其中一个父节点变为另一个父节点的父节点
num[t2] += num[t1] + w;
if ( ans < num[t2] ) ans = num[t2];
}
}
if( fl ) {
printf("%d\n", ans);
continue;
}
printf("YES\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: