24h購物| | PChome| 登入
2012-10-11 09:17:14| 人氣1,063| 回應0 | 上一篇 | 下一篇

[UVA][另類MST] 11747 - Heavy Cycle Edges

推薦 0 收藏 0 轉貼0 訂閱站台

Problem F: Heavy Cycle Edges

Given an undirected graph with edge weights, a minimum spanning tree is a subset of edges of minimum total weight such that any two nodes are connected by some path containing only these edges. A popular algorithm for finding the minimum spanning tree T in a graph proceeds as follows:

  • let T be initially empty
  • consider the edges e1, ..., em in increasing order of weight
    • add ei to T if the endpoints of ei are not connected by a path in T

An alternative algorithm is the following:

  • let T be initially the set of all edges
  • while there is some cycle C in T
    • remove edge e from T where e has the heaviest weight in C

Your task is to implement a function related to this algorithm. Given an undirected graph G with edge weights, your task is to output all edges that are the heaviest edge in some cycle of G.

Input Format

The first input of each case begins with integers n and m with 1 ≤ n ≤ 1,000 and 0 ≤ m ≤ 25,000 where n is the number of nodes and m is the number of edges in the graph. Following this are m lines containing three integers u, v, and w describing a weight w edge connecting nodes u and v where 0 ≤ u, v < n and 0 ≤ w < 231. Input is terminated with a line containing n = m = 0; this case should not be processed. You may assume no two edges have the same weight and no two nodes are directly connected by more than one edge.

Output Format

Output for an input case consists of a single line containing the weights of all edges that are the heaviest edge in some cycle of the input graph. These weights should appear in increasing order and consecutive weights should be separated by a space. If there are no cycles in the graph then output the text forest instead of numbers.

Sample Input

3 3
0 1 1
1 2 2
2 0 3
4 5
0 1 1
1 2 2
2 3 3
3 1 4
0 2 0
3 1
0 1 1
0 0

Sample Output

3
2 4
forest


原本 MST 通常是 P法跟 K法這兩種方法去求,
這裡他給了一個特殊的解法,每次找尋環的最大權值並且將它刪除。
這題我沒有什麼想法,先將最大權值邊做排序後,依序窮舉是否是環上的邊,若是則將它刪除。

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <queue>
using namespace std;
typedef struct {
int i, j, v;
} E;
E D[25005];
vector<int> g[1005];
int cmp(const void *i, const void *j) {
static E *a, *b;
a = (E *)i, b = (E *)j;
return b->v - a->v;
}
int main() {
int n, m, i, j;
int x, y, v;
while(scanf("%d %d", &n, &m) == 2) {
if(n == 0) break;
for(i = 0; i < n; i++)
g[i].clear();
for(i = 0; i < m; i++) {
scanf("%d %d %d", &D[i].i, &D[i].j, &D[i].v);
g[D[i].i].push_back(D[i].j);
g[D[i].j].push_back(D[i].i);
}
qsort(D, m, sizeof(E), cmp);
int tn;
vector<int> buf;
char used[n];
for(i = 0; i < m; i++) {
for(j = 0; j < n; j++) used[j] = 0;
used[D[i].i] = 1;
queue<int> Q;
Q.push(D[i].i);
while(!Q.empty()) {
tn = Q.front();
Q.pop();
for(j = 0; j < g[tn].size(); j++) {
if(tn == D[i].i && g[tn][j] == D[i].j) continue;
if(!used[g[tn][j]]) {
used[g[tn][j]] = 1;
Q.push(g[tn][j]);
}
}
}
if(used[D[i].j]) {
for(vector<int>::iterator it = g[D[i].i].begin();
it != g[D[i].i].end(); ) {
if(*it == D[i].j) {
it = g[D[i].i].erase(it);
break;
} else {
it++;
}
}
for(vector<int>::iterator it = g[D[i].j].begin();
it != g[D[i].j].end(); ) {
if(*it == D[i].i) {
it = g[D[i].j].erase(it);
break;
} else {
it++;
}
}
buf.push_back(D[i].v);
}
}
if(buf.size()) {
for(i = buf.size()-1; i >= 0; i--) {
printf("%d", buf[i]);
if(i) putchar(' ');
}
puts("");
} else
puts("forest");
}
return 0;
}
 

台長: Morris
人氣(1,063) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][spfa] 10278 - Fire Station
此分類上一篇:[UVA][dfs] 10624 - Super Number

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文