原题:http://acm.hdu.edu.cn/showproblem.php?pid=4514
还是练得太少,去年准备复试时,每每遇到连通性问题,刚开始总是想到是需要实现图的表示,再遍历求解,后来看到牛人都是一个并查集便可轻松解决;
还是平时练得少,学习即使练,也没有高度的集中精力,往后的学习也应该有这种高度集中解决问题的专注力。
该题解法要点:
1)构建并查集,若发现新加入的两个节点共享一个根节点,则有环;
2)每合并两个节点node1、node2,则新的根节点sum = node1.sum + node2.sum + weight(node1, node2)
#include <iostream>
#include <algorithm>
using namespace std;
class BCJ {
public:
int next;
int sum;
bool operator < (BCJ b) {
return this->sum < b.sum;
}
};
BCJ bcj[100001];
BCJ tbcj = {-1, 0};
int find(int index)
{
while(bcj[index].next >= 0)
index = bcj[index].next;
return index;
}
void merge(int a , int b, int weight)
{
a = find(a);
b = find(b);
bcj[a].next = b;
bcj[b].sum += bcj[a].sum + weight;
}
int main() {
int n, m, start, end, weight, i, root1, root2;
bool hasCircle;
while(cin>>n>>m) {
//init
hasCircle = false;
fill_n( bcj, n + 1, tbcj);
for(i = 0 ; i < m ; i++) {
cin>> start >> end >> weight;
root1 = find(start);
root2 = find( end);
if(root1 != root2) {
merge(root1, root2, weight);
} else {
hasCircle = true;
}
}
if( hasCircle) {
cout << "YES" <<endl;
} else {
cout << max_element(bcj + 1 , bcj + n + 1)->sum << endl;
}
}
return 0;
}