zoukankan      html  css  js  c++  java
  • 洛谷1525并查集+分集合

    题目链接:https://www.luogu.com.cn/problem/list?keyword=1525&page=1

    题目给出一些点对之间的权值,要求把点对分到两个集合之中,使得两个集合中的最大边的值最小。我们考虑到将点对分成两个集合可以用并查集的分集合方法得到,1-n表示的是一个集合,n+1-2*n表示的是另一个集合,因为我们不会人为的将x和x+n合并,所以x+n所在集合与x所在的集合一定是相互排斥的,也就是说x+n集合是所有不和x一个集合的结点构成的集合。本题只要贪心地扫一遍最大边就可以。将边排序之后我们逐个选择最大边,分为两种情况。

    1、如果最大边的两个结点不在同一个集合中,我们就把他分到两个集合中,因为如果合并到一个集合之中就已经结束了,但是接下来可能会有更小的边满足条件,所以分在两个集合之中。

    2、如果最大边的两个结点已经在同一个集合中,这条边就是答案,因为他们已经是某个集合中的最大边,而且两个集合中已经没有任何一条边比它大。此时就实现了最大边的最小化。

    代码如下:

     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 struct node{
    30     int u,v,w;
    31 }p[maxn];
    32 int f[maxn];
    33 void init()
    34 {
    35     f(i,1,2*n)f[i]=i;
    36 }
    37 int find(int x )
    38 {
    39     return x==f[x]?x:f[x]=find(f[x]);
    40 }
    41 bool cmp(node& a,node& b)
    42 {
    43     return a.w>b.w;
    44 }
    45 int main()
    46 {
    47     //freopen("input.txt","r",stdin);
    48     //freopen("output.txt","w",stdout);
    49     std::ios::sync_with_stdio(false);
    50     n=read(),m=read();
    51     init();
    52     f(i,1,m)
    53     {
    54         p[i].u=read(),p[i].v=read(),p[i].w=read();
    55     }
    56     sort(p+1,p+m+1,cmp);
    57     f(i,1,m)
    58     {
    59         int x=find(p[i].u);
    60         int y=find(p[i].v);
    61         if(x==y)
    62         {
    63             pf("%d",p[i].w);
    64             return 0;
    65         }
    66         else
    67         {
    68             f[x]=find(n+p[i].v);//注意传的是结点 
    69             f[y]=find(n+p[i].u);
    70         }
    71     }
    72     pf("0");
    73     return 0;
    74  } 
  • 相关阅读:
    计算机算法设计与分析之棋盘覆盖问题
    在uboot里面加入环境变量使用run来运行
    软件project师的属性与发展
    Oracle 表三种连接方式(sql优化)
    POJ 1700 cross river (数学模拟)
    八:Java之I/O
    为 Python Server Pages 和 Oracle 构建快速 Web 开发环境。
    WebBot
    WebBrowserProgramming
    Skulpt
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12566947.html
Copyright © 2011-2022 走看看