NOIP2010 关押罪犯

快排+贪心+并查集
过程:
 从大到小快排一遍,因为要求最大怨气值最小,所以每次要删除边,然后分成两个集合。
 对于之前没有确定关系的两个人,分别确定这两个人为敌人关系(因为数据从大到小保证有序),所以一定不能把他们放在同一监狱。
 对于之前某个人已经确定关系,则让未确定关系的人和已确定关系的人的敌人同属一个集合,让未确定关系的人的敌人和已确定关系的人同属一个集合。
 如果两个人的祖先相同,那么这条边一定是最大的怨气值,输出即可。(因为数据保证有序了。)

program prison; 

type date=record 
		l,r,v:longint; 
	end; 

var 
	a:array[1..100000]of date; 
	fa:array[1..20000]of longint; 
	dui:array[1..20000]of longint; 
	n,m,i,j,ans:longint; 

procedure qsort(he,ti:longint); 
var 
	i,j,x:longint;
	y:date; 
begin 
	i:=he;
	j:=ti;
	x:=a[(i+j)>>1].v; 
	repeat 
		while a[i].vx do dec(j); 
		if i<=j then 
			begin 
				y:=a[i]; 
				a[i]:=a[j]; 
				a[j]:=y; 
				i:=i+1; 
				j:=j-1; 
			end;//if 
	until i>j;//repeat 
	if he0 do 
		begin 
			if find(a[i].l)=find(a[i].r) then 
				begin 
					ans:=a[i].v;
					break;
				end; 
			if (dui[a[i].l]=0) and (dui[a[i].r]=0) then 
				begin 
					dui[a[i].l]:=a[i].r; 
					dui[a[i].r]:=a[i].l; 
				end
			else 
				begin 
					if dui[a[i].l]<>0 then 
						begin 
							union(dui[a[i].l],a[i].r); 
							if dui[a[i].r]=0 then dui[a[i].r]:=a[i].l; 
						end;
					if dui[a[i].r]<>0 then 
						begin 
							union(dui[a[i].r],a[i].l); 
							if dui[a[i].l]=0 then dui[a[i].l]:=a[i].r; 
						end;
				end;
			dec(i); 
		end;
	writeln(ans); 
end.


 

你可能感兴趣的:(2010,date,function)