洛谷1525 关押罪犯题解

题目传送门:https://www.luogu.org/problemnew/show/P1525

垃圾并查集直接上程序:好吧还是稍微解释一下,思路类似团伙(看什么题都像团伙,我之前那道我也拿团伙做20分:( ),利用贪心的思想,大的边我都不连,先将w数组从大到小排序,x和y数组,b数组记录i第一个敌人,然后之后再把敌人的敌人连起来,直到找到在同一个集合里的两个点。

#include<stdio.h>
#include<stdlib.h>
int x[200001]={0},y[200001]={0},w[200001]={0},father[200001]={0},b[200001]={0};
int n,m;
int max(int p,int q)
{
    if(p>q)
      return p;
    else return q;
}
void swap(int p,int q)
{
    int t;
    t=x[p];x[p]=x[q];x[q]=t;
    t=y[p];y[p]=y[q];y[q]=t;
    t=w[p];w[p]=w[q];w[q]=t;
    return;
}
int quicksort(int left,int right)
{
    int i,j,mid;
    i=left;j=right;mid=w[(i+j)/2];
    while(i<=j)
    {
    while(w[i]>mid)  i++;
    while(w[j]<mid)  j--;
    if(i<=j)
    {
    swap(i,j);
    i++;j--;
    }
    }
    if(i<right)  quicksort(i,right);
    if(j>left)   quicksort(left,j);
    return 0;
}
int find(int a)
{
    if(a!=father[a])
      father[a]=find(father[a]);
    return father[a];
}
int unit(int r1,int r2)
{
    father[r2]=r1;
    return 0;
}
int main()
{
    int r1,r2,r3,r4,i,ans,max1=-1;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
      father[i]=i;
    for(i=1;i<=m;i++)
    {
      scanf("%d%d",&x[i],&y[i]);
      scanf("%d",&w[i]);
    }
    quicksort(1,m);
    ans=0;
    for(i=1;i<=m+1;i++)
    {
    r1=find(x[i]);r2=find(y[i]);
    if(r1==r2)  {printf("%d\n",w[i]);break;}
    if(b[x[i]]==0)  b[x[i]]=y[i];
    else {r3=find(b[x[i]]);unit(r3,r2);}
    if(b[y[i]]==0)  b[y[i]]=x[i];
    else {r4=find(b[y[i]]);unit(r4,r1);}
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40892508/article/details/81661177