zoukankan      html  css  js  c++  java
  • hdu3367 Pseudoforest

    题意:

    对当前的一个图,求一个最大的伪森林,即边权值最大,每一个连通分量至多含有一个圈的森林。

    分析:

    类似于求一个最大生成树,先将边权值排序,之后就是一个加边合并的过程,俩点所在边可以加入到当前集合有俩个条件:

    1.两点在两个集合,且有至少一个集合没有环

    2.两点在一个集合,且这个集合没有环

    hdu3367
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct edge
    {
    int u,v,c;
    }e[100005];
    int f[10005],n,m;
    bool ee[100005],ff[10005];
    __int64 total;
    bool cmp(edge a,edge b)
    {
    return a.c>b.c;
    }
    void init()
    {
    memset(ee,false,sizeof(ee));
    memset(ff,false,sizeof(ff));
    for(int i=0;i<n;i++)
    f[i]=i;
    }
    int find(int x)
    {
    if(x==f[x])
    return f[x];
    f[x]=find(f[x]);
    return f[x];
    }
    void Union(int x,int y,int c)
    {
    int a=find(x);
    int b=find(y);
    if(a==b) {//俩点在同一个集合,则当前若已经包含有环,则该边不可加入
    if(ff[a])return ;
    total+=c;
    ff[a]=true;
    }
    else {
    if(ff[a]&&ff[b]) return ;//俩点不在同一个集合,则当俩个集合都已经包含有环时,不可加入
    total+=c;
    f[b]=a;
    if(ff[a] ||ff[b])
    ff[a]=true;
    }
    }
    int main()
    {
    while(scanf("%d %d",&n,&m)==2 && (n||m))
    {
    init();
    for(int i=0;i<m;i++)
    scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].c);
    sort(e,e+m,cmp);//将边从大到小排序
    total=0;
    for(int i=0;i<m;i++)
    Union(e[i].u,e[i].v,e[i].c);
    printf("%I64d\n",total);
    }
    return 0;
    }
  • 相关阅读:
    ICON 收集
    vs2015with_update_3
    文件大全,以后就从这些格式入手fuzz
    诗词
    tools URL 收集
    (四)ORBSLAM运动估计
    (三)ORB特征匹配
    (二)ORB描述子提取源码思路与实现
    (一)ORB描述子提取
    双目立体匹配——归一化互相关(NCC)
  • 原文地址:https://www.cnblogs.com/nanke/p/2344629.html
Copyright © 2011-2022 走看看