集合划分(Partition)
[问题描述]
给定一个集合X = {x1, x2, x3…xn}。
定义函数D[xu, xv]:D[xu, xv] = D[xv, xu]且D[xu, xu] = 0。
一个partition是指一种将X划分为K个不相交的子集T = (C1, C2…CK)。CP是X的一个非空子集。
定义一个partition的费用Cost(T) = min{D[u, v]},其中u属于Cp、v属于Cq且有p <>q。
[编程任务]
给定N、K和D,求一个划分使其费用最大。
[输入文件]input.txt。
N K
然后一个N * N的矩阵,第i行j列描述D[i, j]。
[输出文件]output.txt。
你所找到的最大费用。
[样例输入输出]
Input.txt
4 3
0 1 2 3
1 0 2 3
2 2 0 3
3 3 3 0
Output.txt
2
[数据约定]
1 < k <= n <= 200
0 <= D[u, v] <= 32000
对于50%的数据满足k <= 10
===========================
数细胞问题
==================================
var
map:array[1..200,1..200]of longint;
f_bo:array[1..200]of boolean;
dui:array[1..200000]of longint;
n,k,max,k_s:longint;
procedure init;
begin
assign(input,'partition.in');
assign(output,'partition.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure bfs(t,std:longint);
var
l,r:longint;
i:longint;
x:longint;
begin
l:=0; r:=1;
dui[1]:=t;
repeat
inc(l);
x:=dui[l];
for i:=1 to n do
if (f_bo[i])and(map[x,i]<std) then
begin
f_bo[i]:=false;
inc(r);
dui[r]:=i;
end;
until l>=r;
end;
function pd(std:longint):boolean;
var
i:longint;
k_s:longint;
begin
fillchar(f_bo,sizeof(f_bo),true);
k_s:=0;
for i:=1 to n do
if f_bo[i] then
begin
f_bo[i]:=false;
bfs(i,std);
inc(k_s);
end;
if k_s>=k then exit(true)
else exit(false);
end;
procedure main;
var
i,j:longint;
l,r,m:longint;
ans:longint;
begin
readln(n,k);
if n=k then
begin
max:=maxlongint;
for i:=1 to n do
for j:=1 to n do
begin
read(map[i,j]);
if (max>map[i,j])and(i<>j)then max:=map[i,j];
end;
writeln(max);
terminate;
end
else
begin
max:=0;
for i:=1 to n do
for j:=1 to n do
begin
read(map[i,j]);
if max<map[i,j] then max:=map[i,j];
end;
l:=0; r:=max;
while l<=r do
begin
m:=(l+r) shr 1;
if pd(m) then
begin
ans:=m;
l:=m+1;
end
else r:=m-1;
end;
end;
writeln(ans);
end;
begin
init;
main;
terminate;
end.