hdu 3367 Pseudoforest (最大生成树 最多存在一个环)
生活随笔
收集整理的這篇文章主要介紹了
hdu 3367 Pseudoforest (最大生成树 最多存在一个环)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3367
Pseudoforest
Time Limit: 10000/5000 MS (Java/Others)????Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2870????Accepted Submission(s): 1126
?
Input The input consists of multiple test cases. The first line of each test case contains two integers, n(0 < n <= 10000), m(0 <= m <= 100000), which are the number of the vertexes and the number of the edges. The next m lines, each line consists of three integers, u, v, c, which means there is an edge with value c (0 < c <= 10000) between u and v. You can assume that there are no loop and no multiple edges.The last test case is followed by a line containing two zeros, which means the end of the input.
?
Output Output the sum of the value of the edges of the maximum pesudoforest.?
Sample Input 3 3 0 1 1 1 2 1 2 0 1 4 5 0 1 1 1 2 1 2 3 1 3 0 1 0 2 2 0 0?
Sample Output 3 5?題目大意:在一個無向圖中,給定一些邊的聯通情況以及邊的權值,求最大生成樹(最多存在一條環路)。
?
解題思路:用kruskal的方法按照求最大生成樹那樣求的,只不過要加一個判斷,就是判斷兩顆子樹是夠成環,
如果各成環,就不能合并,如果只有其中一個成環或者都不成環,那么就可以合并,并對其進行標記。。。
AC代碼:
20041234 2017-03-08 16:17:45 Accepted 3367 546MS 2668K 1272 B G++#include <stdio.h> #include <string.h> #include <algorithm>using namespace std;struct point {int u,v,l; }p[100010]; int parent[10010],n,m,vis[10010]; // vis數組用來標記是否形成環 bool cmp(point a, point b) {return a.l > b.l; // 從大到小排列 }int find (int x) {int s,tmp;for (s = x; parent[s] >= 0; s = parent[s]);while (s != x){tmp = parent[x];parent[x] = s;x = tmp;}return s; } void Union(int A, int B) {int a = find(A), b = find(B);int tmp = parent[a]+parent[b];if (parent[a] < parent[b]){parent[b] = a;parent[a] = tmp;}else{parent[a] = b;parent[b] = tmp;} } int kruskal() {int sum = 0,max = 0;sort(p,p+m,cmp);memset(vis,0,sizeof(vis));memset(parent,-1,sizeof(parent));for (int i = 0; i < m; i ++){int u = find(p[i].u), v = find(p[i].v);if (u != v){if (vis[u] && vis[v]) continue; // 如果兩棵子樹,各自能夠形成一個環,則不合并 if (vis[u] || vis[v]) // 如果只有其中一個形成環,或者兩個都沒形成環,合并同時標記 vis[u] = vis[v] = 1;max += p[i].l;Union(u,v);}else if(!vis[u] || !vis[v]) // 在同一連通分量內且有一個或者兩個都沒形成環 合并且標記 {vis[u] = vis[v] = 1;max += p[i].l;Union(u,v);}}return max; } int main () {while (scanf("%d%d",&n,&m),n+m!=0){for (int i = 0; i < m; i ++)scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].l);printf("%d\n",kruskal());}return 0; }?
轉載于:https://www.cnblogs.com/yoke/p/6520080.html
總結
以上是生活随笔為你收集整理的hdu 3367 Pseudoforest (最大生成树 最多存在一个环)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 批量修改dos文件到unix
- 下一篇: pod 更新 升级