pascal如何求最大强连通分量

附个例题:
Victoria是一位颇有成就的艺术家,他因油画作品《我爱北京天安门》闻名于世界。现在,他为了报答帮助他的同行们,准备开一个舞会。
Victoria准备邀请n个已经确定的人,可是问题来了:
这n个人每一个人都有一个小花名册,名册里面写着他所愿意交流的人的名字。比如说在A的人名单里写了B,那么表示A愿意与B交流;但是B的名单里不见的有A,也就是说B不见的想与A交流。但是如果A愿意与B交流,B愿意与C交流,那么A一定愿意与C交流。也就是说交流有传递性。
Victoria觉得需要将这n个人分为m组,要求每一组的任何一人都愿意与组内其他人交流。并求出一种方案以确定m的最小值是多少。
注意:自己的名单里面不会有自己的名字。
请详细说明一下,最好有代码和解释,好的一定追加财富!!!

法1:深搜;
法2:用图的传递闭包思想,这里给你一个求最大连通分量和求边权和最大的连通分量的程序program liantong_example;
const
maxv=20;
var
link,longlink:array[1..maxv,1..maxv] of boolean;
f:array[1..maxv] of boolean;
w:array[1..maxv] of integer;
v,e,k,i,j,s,best,besti,max,maxk:integer;
procedure init;
begin
assign(input,'liantong.in');
reset(input);
assign(output,'liantong.out');
rewrite(output);
fillchar(longlink,sizeof(longlink),0);
fillchar(link,sizeof(link),0);
readln(v);
for i:=1 to v do
readln(w[i]);
readln(e);
for k:=1 to e do
begin
readln(i,j);
link[i,j]:=true;
link[j,i]:=true;
end;
end;{init}
procedure bibao;
begin
longlink:=link;
for k:=1 to v do
for i:=1 to v do
for j:=1 to v do
longlink[i,j]:=longlink[i,j] or (longlink[i,k] and longlink[k,j]);
end;{bibao}
procedure dfs(i:integer); {深度优先搜索,用于输出路径}
begin
write(i,'->');
f[i]:=true;
for j:=1 to v do
if (not f[j]) and longlink[i,j]
then dfs(j);
end;{dfs}
begin{main}
init;
bibao;
for i:=1 to v do
begin
k:=0;s:=0;
for j:=1 to v do {计算顶点i所在连通分支中的顶点总数和顶点的权和}
if longlink[i,j]
then begin
k:=k+1;
s:=s+w[j];
end;
if k>best {求出顶点数的最大值}
then begin
best:=k;
besti:=i;
end;
if s>max {求出顶点权和的最大值}
then begin
max:=s;
maxk:=i;
end;
if k=v then break;
end;
fillchar(f,sizeof(f),false); {结点是否访问数组初始化}
dfs(besti);
writeln;
fillchar(f,sizeof(f),false);
dfs(maxk);
close(input);
close(output);
end.
温馨提示:答案为网友推荐,仅供参考
相似回答