发布网友 发布时间:2024-10-23 16:54
共3个回答
热心网友 时间:2024-11-06 05:41
确实如楼上所述,只有进行回溯迭代来求解。
不过你可以加一些优化来减少不必要的回溯。
我大概看了你的程序,可以优化的地方有很多。
我这里直接改写一下:
var b:array[1..1000] of integer;//用记录集中的相邻节点,可以节省下pd函数。
procedure search(max,t:longint);
var
i,j:longint;
begin
if (max+n-t<=ans) then exit;//强剪枝,当前数量+剩余数量<=最大结果时,返回。
if t>=n then
begin
if max>ans then
begin
ans:=max;
for i:=1 to n do
begin
a[i]:=s[i];
end;
exit;
end;
end;
for i:=t to n do
begin
if (b[i]=0) then //当前集与该节点不相邻
begin
s[i]:=1;
for j:=t+1 to n do b[j]:=b[j]+g[i,j];//邻接矩阵用1,0储存,1为邻接,读入的时候赋值g[j,i]:=g[i,j]=1
search(max+1,i+1);
for j:=t+1 to n do b[j]:=b[j]-g[i,j];
s[i]:=0;
end else search(max,i+1);
end;
end;
你用这个跑一下试试,还有一些优化手段,你可以仔细想想。
热心网友 时间:2024-11-06 05:45
有数据范围吗?
= =
好吧仔细看了看这道题是求一般图的最大集啊
NP-C问题
简单的说就是只能暴搜= =
但是暴搜的技巧有很多 例如可行性剪枝 最优性剪枝
加上这些应该就可以了
等我拍一份代码
==================================
顺便一提 祝Pascal选手早日转C
==================================
var只拍了你给的样例
有问题问我
【不过我对会不会T不是很有自信= =先测一下试试看?】
复杂度是裸的O(2^n * (n + m))
热心网友 时间:2024-11-06 05:42
var
a:array[1..200,1..200] of boolean;
b:array[1..200] of integer;
c:array[1..200] of boolean;
n,m:integer;
i,j,k,p,q:integer;
max,num:integer;
f:text;
begin
for i:=1 to 200 do for j:=1 to 200 do a[i,j]:=false;
assign(f,'集.in'); reset(f);
readln(f,n,m);
for i:=1 to m do begin readln(f,p,q); a[p,q]:=true; a[q,p]:=true; end;
close(f);
for i:=1 to n do c[i]:=true;
repeat
for i:=1 to n do begin
b[i]:=0;
for j:=1 to n do if a[i,j] then inc(b[i]);
end;
num:=0;
for i:=1 to n do if b[i]>0 then inc(num);
if num>0 then begin
max:=b[1];
k:=1;
for i:=2 to n do if b[i]>=max then begin k:=i; max:=b[i]; end;
{带等号则序号小的优先,否则序号大的优先}
for i:=1 to n do begin a[i,k]:=false; a[k,i]:=false; end;
c[k]:=false;
end;
until num=0;
for i:=1 to n do if c[i] then write(i:3);
end.