码迷,mamicode.com
首页 > 其他好文 > 详细

luogu1525关押罪犯

时间:2018-04-08 11:27:35      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:ret   根据   color   using   include   理解   节点   main   can   

#这题用并查集!!

刚一开始看的时候懵了,这题怎么做,后来看了一下别人的题解,别人也没怎么说明白,最后自己根据别人的代码手动模拟了一下。跟你们说下我的理解与感悟。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define X 100000+7
using namespace std;
int fa[X];//父亲
struct Node{
    int u,v,w;
}map[X];//罪犯之间的关系
bool pd(Node a,Node b)
{
    return a.w>b.w;
}//重新定义sort的排序,由大到小排序
int find(int x)
{
    if(fa[x]==x)return x;
    return fa[x]=find(fa[x]);    
}//查找父亲节点
int hb(int x,int y)
{
    int ff=find(x),fff=find(y);
    fa[ff]=fff;
}//并查集的合并
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
  for(int i=1;i<=2*n;++i)//这里是一个难点,有的同学就要问了,为什么i要在1和2*n之间定义呢,我们是把n+1~2*n定义为1~n罪犯的敌人(互相看不服的罪犯)为什么要用2*n呢,因为n是不确定的,要找到他的敌人,就要开2倍的数组
{ fa[i]
=i; } for(int i=1;i<=m;++i) { scanf("%d%d%d",&map[i].u,&map[i].v,&map[i].w); } sort(map+1,map+m+1,pd);//这里由大到小排序,运用了贪心思想。因为要保证看到的最小,所以要保证俩个火气大的罪犯分开
 
for(int i=1;i<=m;++i) { int ff=find(map[i].u),fff=find(map[i].v); if(ff==fff)//如果俩互相看不服对方的罪犯在同一监狱,就输出他们之间的火气值,因为火气值是从大到小排序的,之后就算有互相看不服的罪犯在同一监狱,也比此时的火气值小
{ cout
<<map[i].w; return 0; } hb(map[i].u,map[i].v+n);//这时要让互相看不服对方的X,Y。X要与Y之后看不服的罪犯合住一监狱 hb(map[i].v,map[i].u+n);//同上 } cout<<0;//若最后没有发生火气值,直接输出就好了 }

 

luogu1525关押罪犯

标签:ret   根据   color   using   include   理解   节点   main   can   

原文地址:https://www.cnblogs.com/tpgzy/p/8743787.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!