并查集+贪心算法。
/* 对于稀疏图来说,用Kruskal写最小生成树效率更好。 输入:边的起点,终点,权值 */ #include <iostream> using namespace std; #define Max 100 struct Edge { int start,end,w; }; Edge e[Max]; int cnt, father[Max]; void init() { cnt = 0; for (int i = 1; i < Max; ++i) { father[i] = i; } } int find(int x) { if (x != father[x]) { father[x] = find(father[x]); } return father[x]; } void union_set(int i) { int x = find(e[i].start); int y = find(e[i].end); if (x != y) { father[x] = y; cnt++; } } bool cmp(Edge a, Edge b) { return a.w < b.w; } void Kruskal(int n, int m) { sort(e+1, e+n+1, cmp); for (int i = 1; i <= n; ++i) { if (cnt == m-1) break; union_set(i); } } int main() { int n, m;//n为边数,m为点数 cin >> n >> m; for (int i = 1; i <= n; ++i) { cin >> e[i].start >> e[i].end >> e[i].w; } init(); Kruskal(n, m); if (cnt == m-1) cout << "Yes" << endl; else cout << "No" << endl; system("pause"); }
题目:HDU 1863 畅通工程 http://acm.hdu.edu.cn/showproblem.php?pid=1863