1. 程式人生 > >洛谷 1525 關押罪犯

洛谷 1525 關押罪犯

一道並查集,按照一般的思路是不能處理某一些情況的。

例如

1——2 3——4 1——5 3——5 在安排第二個關係的時候不確定把3放到1還是放到2,而這個關係的放置會直接影響第三個關係。當時想了好久都沒有思路, 後來看了別人的程式碼,是用一個數組記錄敵人的資訊。這個用的真的很巧妙,用了這個陣列之後,對於第二個關係來說,他們和第一個都沒有關係,那著兩個關係就不要合併,就避免了合併產生的錯誤。

//關押罪犯
#include <bits/stdc++.h>
using namespace std;
const int maxn=100000+5;
int fa[20005];
int N,M;
int enemy[20005];
struct Node{
	int a,b,c;
	bool operator<(const Node x)const{
		return this->c<x.c;
	}
}; 

int find(int x)
{
	if(x==fa[x]) return x;
	else return fa[x]=find(fa[x]);
}

void unit(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y) return;
	fa[x]=y;
}

void init()
{
	for(int i=1;i<=N;i++)
		fa[i]=i;
}

int main()
{
	priority_queue<Node> q;
	int a,b,c;
	cin>>N>>M;
	int i,j,k;
	for(i=0;i<M;i++){
		scanf("%d%d%d",&a,&b,&c);
		q.push((Node){a,b,c});
	}
	Node temp;
	init();
	while(!q.empty())
	{
		temp=q.top();
		q.pop();
		if(find(temp.a)==find(temp.b)){
			printf("%d",temp.c); 
			return 0;
		}	
		if(!enemy[temp.a]) enemy[temp.a]=temp.b;
		else unit(enemy[temp.a],temp.b);
		if(!enemy[temp.b]) enemy[temp.b]=temp.a;
		else unit(enemy[temp.b],temp.a);
	} 
	printf("0");
	return 0;
}