zoukankan      html  css  js  c++  java
  • uva 11747,kruskal 并查集

    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
    

    Zachary Friggstad

    参考了网上题解。

    并查集,kruskal变形,很巧妙的算法。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<stack>
    
    using namespace std;
    
    #define LL long long
    #define UINT unsigned int
    #define MAX_INT 0x7fffffff
    #define cint const int
    
    #define MAXN 1111
    #define MAXM 25555
    
    struct edge{
        int u, v, w, nxt;
        bool operator < (const edge &rhs)const{
            return w<rhs.w;
        }
    }e[MAXM];
    int h[MAXN], cc, n, m;
    
    void add(int u, int v, int w){
        e[cc]=(edge){u, v, w, h[u]};
        h[u]=cc++;
    }
    
    bool ve[MAXM];
    int p[MAXN];
    
    int finds(int x){
        if(p[x]==-1) return x;
        else return (p[x] = finds(p[x]));
    }
    
    void mst(){
        sort(e, e+cc);
        int i, j;
        fill_n(p, n, -1);
        fill_n(ve, cc, false);
        for(i=j=0; i<cc; i++){
            int fx = finds(e[i].u), fy = finds(e[i].v);
            if(fx!=fy){
                p[fx] = fy;
                ve[i] = true;
            }
        }
    }
    
    int main(){
    //    freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        while(scanf(" %d %d", &n, &m)==2 && (n || m)){
            if(!n || !m){
                printf("forest
    ");        continue;
            }
            int i, u, v, w;
            fill_n(h, n, -1);       cc=0;
            for(i=0; i<m; i++){
                scanf(" %d %d %d", &u, &v, &w);
                add(u, v, w);
            }
    
            mst();
            vector<int> ans;
            for(i = 0; i < cc; i++) if(!ve[i])
                ans.push_back(e[i].w);
            if(!ans.size()){
                printf("forest
    ");     continue;
            }
            printf("%d", ans[0]);
            for(i=1; i<ans.size(); i++)
                printf(" %d", ans[i]);
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    Linux0.11内核--fork进程分析
    Linux0.11内核--内存管理之1.初始化
    Linux0.11内核--进程调度分析之2.调度
    Linux0.11内核--进程调度分析之1.初始化
    github
    推荐大家一个靠谱的论文检测平台。重复的部分有详细出处以及具体修改意见,能直接在文章上做修改,全部改完一键下载就搞定了。他们现在正在做毕业季活动, 赠送很多免费字数,可以说是十分划算了!地址是:https://www.paperpass.com/
    妈妈再也不用担心我找idea激活码了
    eclipse集成tomcat
    DNS--localhost
    RFC 2819)第5节"Definitions"除外的全部内容
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3375336.html
Copyright © 2011-2022 走看看