码迷,mamicode.com
首页 > 其他好文 > 详细

LA 6476 Outpost Navigation 解题报告

时间:2015-02-16 00:24:29      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:

题目链接

Solution

  DFS+剪枝

  对于一个走过点k,如果有必要再走一次,那么一定是走过k后在k点的最大弹药数增加了.否则一定没有必要再走.

      记录经过每个点的最大弹药数,对dfs进行剪枝.

 

技术分享
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <map>
using namespace std;
map<string, int> pos;
struct Edge {
    int v, c, next;
} edge[3000];
int head[3000], cnt;
int vis[3000], amm[3000], aim[3000],sum[3000];
int cs, n, m, ans;
string s, t;

void addedge (int u, int v, int c) {
    edge[++cnt].v = v, edge[cnt].c = c;
    edge[cnt].next = head[u];
    head[u] = cnt;
}
void dfs (int x, int s, int k) {
    if(k>=ans) return;
    if (aim[x]) {
        ans = min (ans, k);
        return ;
    }
    if (!vis[x]) s += amm[x], vis[x] = 1;
    if(vis[x]&&sum[x]>=s) return;
    sum[x]=max(sum[x],s);
    for (int i = head[x]; i; i = edge[i].next) {
        int v = edge[i].v, c = edge[i].c;
        if (s >= c)  dfs (v, s - c, k + c);
    }
    vis[x] = 0;
}
int main() {
    scanf ("%d", &cs);
    while (cs--) {
        pos.clear();
        memset (head, 0, sizeof head);
        memset(sum,0,sizeof sum);
        memset(vis,0,sizeof vis);
        cnt = 1, ans = 0x7fffffff;
        scanf ("%d %d", &n, &m);
        for (int i = 1; i <= n; i++) {
            cin >> s;
            pos[s] = i;
            cin >> amm[i] >> s;
            if (s[0] == y) aim[i] = 1;
            else aim[i] = 0;
        }
        for (int i = 1, x; i <= m; i++) {
            cin >> s >> t >> x;
            int u = pos[s], v = pos[t];
            addedge (u, v, x);
            addedge (v, u, x);
        }
        dfs (1, 0, 0);
        if (ans != 0x7fffffff) printf ("%d\n", ans);
        else puts ("No safe path");
    }
}
View Code

 

LA 6476 Outpost Navigation 解题报告

标签:

原文地址:http://www.cnblogs.com/keam37/p/4293607.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!