zoukankan      html  css  js  c++  java
  • hdu3367最大伪森林(并查集)

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3367/

    题目要求一个连通图的最大伪森林,伪森林是一个最多有一个回路的图。我们只要用Kruskal最大生成树的策略就可以,给根节点表上记号表明这棵树有没有负环。其实也有一些贪心的思想。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define mp(a,b) make_pair((a),(b))
    17 #define P pair<int,int>
    18 #define dbg(args) cout<<#args<<":"<<args<<endl;
    19 #define inf 0x3f3f3f3f
    20 const int maxn=1e6+10;
    21 int n,m,t;
    22 inline int read(){
    23     int ans=0,w=1;
    24     char ch=getchar();
    25     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    26     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    27     return ans*w;
    28 }
    29 int f[maxn];
    30 bool mark[maxn];
    31 struct node{
    32     int u,v,w;
    33 }e[maxn];
    34 int ans;
    35 void init()
    36 {
    37     f(i,0,n-1)f[i]=i;
    38     mem(mark,0);
    39     ans=0;
    40 }
    41 bool cmp(node& a,node& b)
    42 {
    43     return a.w>b.w;
    44 }
    45 int find(int x)
    46 {
    47     if(x==f[x])return x;
    48     return f[x]=find(f[x]);
    49 }
    50 void Union(int x,int y,int w)
    51 {
    52     int fx=find(x);
    53     int fy=find(y);
    54     if(fx==fy)
    55     {
    56         if(!mark[fx])
    57         {
    58             mark[fx]=1;
    59             ans+=w;
    60         }
    61     }
    62     else 
    63     {
    64         if(!mark[fx]||!mark[fy])
    65         {
    66             f[fx]=fy;
    67             mark[fy]=mark[fx]||mark[fy];//两者都为零的时候fy不做标记,但是两者中有一个是零的时候就会做标记 
    68             ans+=w;
    69         }
    70     }
    71 }
    72 int main()
    73 {
    74     //freopen("input.txt","r",stdin);
    75     //freopen("output.txt","w",stdout);
    76     std::ios::sync_with_stdio(false);
    77     while(1)
    78     {
    79         n=read(),m=read();
    80         init();
    81         if(n==0&&m==0)break;
    82         f(i,1,m)
    83         {
    84             scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    85         }
    86         sort(e+1,e+m+1,cmp);
    87         f(i,1,m)
    88         {
    89             Union(e[i].u,e[i].v,e[i].w);
    90         }
    91         pf("%d
    ",ans); 
    92     }
    93  } 
  • 相关阅读:
    Centeos7搭建selenium+Chrome浏览器
    数据结构学习篇之栈和队列
    数据结构学习篇之线性表
    Tornado基础学习篇
    Python控制函数运行时间
    python线程实现异步任务
    Python实现几种简单的排序算法
    python爬虫遇到会话存储sessionStorage
    Python 有哪些优雅的代码实现让自己的代码更pythonic?
    Ubuntu查看端口使用情况,使用netstat命令:
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12562098.html
Copyright © 2011-2022 走看看