poj-1724

// 320K 110MS   C++
#include 
#include 

using namespace std;

const int MAX = 110;

struct MapInfo {
    int length;
    int toll;
};

struct Road {
    int end;
    int length;
    int toll;
    int next;
};

typedef struct Road Road;
typedef struct MapInfo MapInfo;

// MapInfo map[MAX][MAX];

Road roads[10010];

int map[MAX];

int curRoadInsertPos;

char visitFlag[MAX];

#define INF 999999

int coinNum;
int minLength = INF;
int cityNum;
int roadNum;

void DFS(int begin, int tollSum, int lengthSum) {
    // printf("DFS %d\n", begin);
    visitFlag[begin] = 1;
    if (begin == cityNum) {
        minLength = minLength < lengthSum ? minLength: lengthSum;
    } else {
        int roadPos = map[begin];

        while(roadPos> 0) {
            int curEnd = roads[roadPos].end;
            int curLength = roads[roadPos].length;
            int curToll = roads[roadPos].toll;
            int curNext = roads[roadPos].next;
            // printf("AAAAAAAA %d %d\n", roads[5].next, roads[roadPos].next);
            // printf("roadPos1 %d\n", roadPos);
            if (!visitFlag[curEnd]) {
                int curTollSum = tollSum + curToll;
                // exceeds the coin or exceed cur min length! cut off branch
                if (curTollSum > coinNum || minLength < lengthSum + curLength) {
                    roadPos = roads[roadPos].next;
                    continue;
                } else {
                    DFS(curEnd, curTollSum, lengthSum + curLength);
                }
            }
            roadPos = roads[roadPos].next;
            // printf("roadPos2 %d\n", roadPos);
        }
    }
    visitFlag[begin] = 0;
}

void getMinLength() {
    DFS(1, 0, 0);
    if (minLength == INF) {
        printf("-1\n");
    } else {
        printf("%d\n", minLength);
    }
}

int main() {
    while(scanf("%d %d %d", &coinNum, &cityNum, &roadNum) != EOF) {
        memset(map, 0, sizeof(map));
        memset(roads, 0, sizeof(roads));
        memset(visitFlag, 0, sizeof(visitFlag));
        curRoadInsertPos = 1;
        minLength = INF;
        for (int i = 1; i <= roadNum; i++) {
            int begin;
            int end;
            int length;
            int toll;
            scanf("%d %d %d %d", &begin, &end, &length, &toll);
            // map[begin][end].length = length;
            // map[begin][end].toll = toll;
            if (map[begin] == 0) {
                // first road node
                roads[curRoadInsertPos].end = end;
                roads[curRoadInsertPos].length = length;
                roads[curRoadInsertPos].toll = toll;
                roads[curRoadInsertPos].next = 0;
                map[begin] = curRoadInsertPos++;
            } else {
                // add new road node
                roads[curRoadInsertPos].end = end;
                roads[curRoadInsertPos].length = length;
                roads[curRoadInsertPos].toll = toll;
                roads[curRoadInsertPos].next = map[begin];
                map[begin] = curRoadInsertPos++;
            }
        }
        getMinLength();
    }
}


DFS的基础变形题吧, 就是加入了一些剪枝的条件:(1)当前要交的路费超过了现金 (2)当前走的路长已经超过, 目前为止的DFS尝试中得到最终结果的情况下的最短总路长(不加这个剪枝会TLE)

有个需要注意的点就是 两个点之间可能不止一条边, 因此不能用邻接矩阵来做,而应该用邻接表来做,并且邻接表的实现也要采用ACM常用的预分配空间+数组index模拟指针的方法来做,不能动态的malloc/new,否则还可能TLE。

你可能感兴趣的:(POJ,搜索,poj)