主题:搜索优化问题
Mato完整版
[专家分:1270] 发布于 2008-07-22 21:01:00
有N个村庄,每两个村庄A和B之间都有两条单向的路:从A到B的和从B到A的,这两条路的长度可能不同。现在有一个人在第1个村庄里,请帮他找一条最短的路,这条路经过除第1个村庄外的每个村庄一次且仅一次,并且最后又回到第1个村庄。
输入:第一行一个数N(2<=N<=14),表示村庄数,接下来有一个N*N的矩阵,第I行第J列的数表示从第I个村庄到第J个村庄之间的路的长度,保证对于任何数I(1<=I<=N),第I行第I列的数总为0。
输出:一个数,表示最短路的长度。
【样例输入】
3
0 3 2
2 0 3
3 2 0
【样例输出】
6
最后更新于:2008-07-24 21:35:00
回复列表 (共3个回复)
沙发
Mato完整版 [专家分:1270] 发布于 2008-07-24 21:37:00
我加了一个剪枝:
如果在第N步时所走的路程已经超过最小值了,或走了M步(1<=M<=N)后所走的路程已经超过(最小值-(N - M)),就可以放弃这条路了。
可是加了这个剪枝以后,最后一组数据还是超时了(2.5s左右),前面9组都对。
这组数据是这样的:
13
0 88 99 13 14 15 16 55 16 52 13 19 1
22 0 44 55 66 96 36 66 66 54 88 99 2
51 52 0 53 54 55 66 75 72 74 73 72 3
54 32 13 0 44 55 66 22 88 77 34 33 4
38 26 38 45 0 58 68 72 75 65 85 11 5
18 12 13 14 15 0 16 25 14 35 52 21 6
71 22 33 45 55 65 0 18 29 87 96 45 7
92 92 26 18 19 21 28 0 18 55 36 32 7
45 56 78 65 65 68 63 62 0 69 69 65 6
32 54 56 69 99 22 33 44 55 0 66 77 6
58 58 59 59 65 65 67 67 63 35 0 58 5
55 66 33 22 44 18 59 69 69 65 63 0 4
12 13 18 19 20 11 18 68 59 38 30 15 0
请问大家还有没有其它的剪枝?
板凳
Mato完整版 [专家分:1270] 发布于 2008-07-24 21:38:00
还有,顺便发一下我的代码:
VAR
a: ARRAY[1..40, 1..40] OF INTEGER;
b: ARRAY[1..40] OF BOOLEAN;
n: INTEGER;
minr: LONGINT;
PROCEDURE inputfile;
VAR
fi: TEXT;
i, j: INTEGER;
BEGIN
ASSIGN(fi, 'E1_8.in');
RESET(fi);
READ(fi, n);
FOR i:=1 TO n DO
FOR j:=1 TO n DO READ(fi, a[i, j]);
CLOSE(fi);
END;
PROCEDURE xxx(ii, k: INTEGER; r: LONGINT);
VAR
i: INTEGER;
BEGIN
IF ii = n THEN
IF r + a[k, 1] < minr THEN minr := r + a[k, 1];
IF ii < n THEN BEGIN
IF r < minr - (n - ii + 1) THEN
FOR i:=2 TO n DO
IF b[i] THEN BEGIN
b[i] := FALSE;
xxx(ii + 1, i, r + a[k, i]);
b[i] := TRUE;
END;
END;
END;
PROCEDURE printfile;
VAR
fo: TEXT;
BEGIN
ASSIGN(fo, 'E1_8.out');
REWRITE(fo);
WRITE(fo, minr);
CLOSE(fo);
END;
BEGIN
inputfile;
FILLCHAR(b, SIZEOF(b), TRUE);
minr := MAXLONGINT;
xxx(1, 1, 0);
printfile;
END.
3 楼
angwuy [专家分:2280] 发布于 2008-07-25 09:20:00
试一下这种优化:
当搜索到:
A→B→C→D
A→C→B→D
这两条时,路径长的直接剪掉
如果实在不行,还可以用搜索的终极绝招:卡时
我来回复