回 帖 发 新 帖 刷新版面

主题:搜索优化问题

有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

回复列表 (共3个回复)

沙发

我加了一个剪枝:
如果在第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

请问大家还有没有其它的剪枝?

板凳

还有,顺便发一下我的代码:
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 楼

试一下这种优化:

当搜索到:
A→B→C→D
A→C→B→D
这两条时,路径长的直接剪掉

如果实在不行,还可以用搜索的终极绝招:卡时

我来回复

您尚未登录,请登录后再回复。点此登录或注册