zoukankan      html  css  js  c++  java
  • HDU 2437 Jerboas (剪枝搜索)

    题意:给定一幅图,图上有两种点T,P.......一只跳鼠在一个T点作为起始点,它想通过图上的路到达某个P点,P点满足如下要求:

    (1).到达P点的途中路径权值为k的倍数

    (2).尽量让路径权值取最小

    (3).权值相同时,P点取更小的


    此题一波三折,一开始反向建图,以为记忆化搜索能过.....TLE了,以为是枚举了是P的点浪费了时间;然后正向建图,从起点开始,也是TLE了,然后发现此题记忆化搜索影响不大,于是剪枝 v < vis[e][v % k] 的值才能继续搜索........剪枝完秒过,看来是卡剪枝的题目.......

    #include <cstdio>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    # define MAX 1111
    # define INF 0x7FFFFFFF
    using namespace std;
    char a[MAX];
    struct node {
        int s,e,v,next;
    } ed[22222];
    int head[MAX],num = 0,n,m,k,st;
    int dp[MAX],vis[MAX][MAX]; //利用整数倍关系,剪枝
    
    void add(int s,int e,int v) {
        ed[num].s = s;
        ed[num].e = e;
        ed[num].v = v;
        ed[num].next = head[s];
        head[s] = num++;
    }
    
    void init() {
        memset(vis,0,sizeof(vis));
        memset(head,-1,sizeof(head));
        num = 0;
    }
    
    int dfs(int v0,int u0,int cur) {
        if(a[v0 - 1] == 'P' && cur % k == 0) return dp[v0] = min(dp[v0],cur);
        if(dp[v0] != INF) return dp[v0];
        for(int i = head[v0]; i != -1; i = ed[i].next) {
            int e = ed[i].e;
            int v = ed[i].v + cur;
            if(vis[e][v%k] == 0 || v < vis[e][v % k]) {
                vis[e][v%k] = v;
                dfs(e,u0,v);
                
            }
        }
    }
    
    int main() {
        int T;
        cin >> T;
        int casee = 1;
        while(T --) {
            init();
    
            cin >> n >> m >> st >> k;
            for(int i=1; i<=n; i++)
                 dp[i] = INF;
    
            getchar();
            int aa,bb,cc;
            scanf("%s",a);
            for(int i=1; i<=m; i++) {
                scanf("%d%d%d",&aa,&bb,&cc);
                add(aa,bb,cc);
            }
            printf("Case %d: ",casee++);
            dfs(st,st,0);
            int flag = 0,ind,ans = INF;
            for(int i=1; i<=n; i++) {
                if(dp[i] != INF) {
                    flag = 1;
                    if(ans > dp[i]) {
                        ans = dp[i];
                        ind = i;
                    }
                }
            }
            if(flag) printf("%d %d
    ",ans,ind);
            else printf("-1 -1
    ");
        }
        return 0;
    }


  • 相关阅读:
    JSP 九大内置对象
    Spring中事务管理的两种方式
    使用java实现圆形运动
    JDBC 详解
    PAT1003 Emergency
    知识点汇总计算机网络(概要版)
    PAT1002
    知识点汇总计算机网络(细节版)
    知识点汇总数据结构(进阶版)
    知识点汇总数据结构(基础版)
  • 原文地址:https://www.cnblogs.com/riskyer/p/3223573.html
Copyright © 2011-2022 走看看