poj-1062-昂贵的聘礼

一个 深度优先搜索以及回溯递归的 经典运用,复杂度是  O(NM)

需要注意的是: 选择的  点俩俩要求 等级限制,以及一个点只能 应用一次, 即使有环 也不要紧。

#include <cstring>
#include <cstdio>
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) < (b) ? (b) : (a))
const int N = 105;
struct Edge {
    int to,val,pre;
    Edge(){}
    Edge(int TO, int VAL, int PRE) : to(TO), val(VAL), pre(PRE){};

    void show() {
        printf ("%d %d %d\n", to, val, pre);
    }
};
int head[N], pos, m, n;
Edge edge[N * N];
int P[N], L[N];
bool flag[N];

void init(){
    memset(head, -1, sizeof head);
    memset(flag,  0, sizeof flag);
    pos = 0;
}

void addEdge(int s, int to, int  val) {
    edge[pos] = Edge(to, val, head[s]);
    head[s] = pos ++;
}

int dfs(int person, int left, int right) {
    if (L[person] + m < right || L[person] - m > left) return 0x7fffffff;
    flag[person] = true;
    int ans = P[person];
    for(int i = head[person]; ~i ; i = edge[i].pre) {
        Edge &tmp = edge[i];
        if (!flag[tmp.to]) {
            int wpd = dfs(tmp.to, min(left, L[tmp.to]), max(right, L[tmp.to]));
            if (wpd == 0x7fffffff) continue;
            wpd += tmp.val;
            ans = min(ans, wpd);
        }
    }
    flag[person] = false;
    return ans;
}

void solve() {
    printf("%d\n", dfs(1, L[1], L[1]));
}

int main() {
    int X, T, V;
    while(~scanf("%d%d", &m, &n)) {
        init();
        for(int i = 1 ; i <= n ; ++i) {
            scanf("%d%d%d", P + i , L + i, &X);
            for( int j = 1 ; j <= X ; ++j) {
                scanf("%d%d", &T, &V);
                addEdge(i, T, V);
            }
        }
        solve();
    }
    return 0;
}

 

posted @ 2017-08-02 11:44  默默无语敲代码  阅读(183)  评论(0编辑  收藏  举报