P1525-關押罪犯【並查集】
阿新 • • 發佈:2018-12-10
正題
題目大意
有n個罪犯,罪犯有些關係,就是表示罪犯i和罪犯j在同一個監獄會造成c的破壞,有兩座監獄,要求分配的使得最大的破壞最小。
解題思路
先按照c排序,然後就從大到小處理直到無法處理。 我們可以用並查集表示在一個監獄中,然後用敵人的敵人是朋友來合併。記錄每個罪犯的敵人的根,然後每次合併就將他的敵人和他的敵人合併在一起,直到發現一個人即是某人的敵人有是某人敵人的敵人就輸出。
code
#include<cstdio>
#include<algorithm>
#define N 20010
using namespace std;
struct node{
int x,y,c;
}a[N*5];
int n,m,father[N],empty[N];
bool cmp(node x,node y)
{return x.c>y.c;}
int find(int x)//尋找
{
if(father[x]==x) return x;
return father[x]=find(father[x]);
}
void unionn(int x,int y)//合併
{
int fa=find(x),fb=find(y);
father[fa]=fb;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].c);
for(int i=1;i<=n;i++)
father[i]=i;
sort(a+1,a+1+m,cmp);
for(int i=1;i<=m;i++)
{
if(find(a[i].x)==find(a[i].y))//出現問題
{
printf ("%d",a[i].c);
return 0;
}
else
{
if(!empty[a[i].x])
empty[a[i].x]=a[i].y;
else
unionn(empty[a[i].x],a[i].y);
if(!empty[a[i].y])
empty[a[i].y]=a[i].x;
else
unionn(empty[a[i].y],a[i].x);
//連線——敵人的敵人
}
}
printf("0");
}