uva 10269 最短路+dp

题意:有a个村庄、b个城镇, 编号分别为:1—a , a+1——a+b 。 有双神奇的鞋,可以瞬时移动,可以使用k次,每次可以移动L , 但穿这双鞋的时候,不能经过城镇 , 问:从a+b 到 1 最短距离是多少?

刚开始看这个题时 , 一点思路都没有 , dp类型的题目做得太少了。

解法:进行状态压缩, 用点+使用鞋子的次数 , 来表示一个状态 , d[i][k] , 表示到 点 i 使用 k 次鞋子的最短距离是多少。

但要先进行初始化 , 求任意点之间不经过城镇的最短距离 , 用floyd算法 , 然后再用SPFA算法来找最短路。

代码:

#include <iostream>
#include <string.h>
#include <vector>
#include <queue>
#include <stdio.h>

using namespace std;

#define maxn 110
#define INF 0xffffff

struct edge
{
    int to;
    int d;
};

int a , b , m , l , k;
int d[maxn][20] , pre[maxn][20];
int dist[maxn][maxn];

void init()
{
    memset(pre ,0 , sizeof(pre));
    for(int i = 1; i <= a+b; i++)
    {
        for(int j = 1; j <= a+b; j++)
            dist[i][j] = INF;
        dist[i][i] = 0;
        grap[i].clear();
    }

}

void floyd()//求任意两点之间不经过城镇的最短距离
{
    int i , j , k;
    for(k = 1; k <= a; k++)
    {
        for(i = 1; i <= a+b; i++)
        {
            for(j = 1; j <= a+b; j++)
            {
                if(k == i || k == j)  continue;
                if(dist[i][k]+dist[k][j] < dist[i][j])
                    dist[i][j] = dist[i][k]+dist[k][j];
            }
        }
    }
}

void spfa()
{
    queue<int>q;
    queue<int>t;
    q.push(a+b) , t.push(0);

    int i , j;
    for(i = 1; i <= a+b; i++)
        for(j = 0; j <= k; j++)
            d[i][j] = INF;
    for(i = 0; i <= k; i++)
        d[a+b][i] = 0;
    int u , v;

    while(!q.empty())
    {
        u = q.front() ; q.pop();
        v = t.front() ; t.pop();
        //cout<<d[u][v]<<endl;
        pre[u][v] = 0;
        for(i = 1; i <= a+b; i++)
        {
            if(u == i)  continue;
            if(d[i][v] > d[u][v]+dist[u][i])
            {
                d[i][v] = d[u][v]+dist[u][i];
                if(!pre[i][v])
                {
                    q.push(i);
                    t.push(v);
                    pre[i][v] = 1;
                }
            }
            if(dist[u][i] <= l && v < k && d[i][v+1] > d[u][v] )
            {
                d[i][v+1] = d[u][v];
                if(!pre[i][v+1])
                {
                    q.push(i);
                    t.push(v+1);
                    pre[i][v+1] = 1;
                }
            }
        }
    }
}

int main()
{
    int t;
    scanf("%d" , &t);
    while(t--)
    {

        scanf("%d %d %d %d %d" , &a , &b , &m , &l , &k);
        init();
        int i , j , x , y , z;
        for(i = 0; i < m; i++)
        {
            scanf("%d %d %d" , &x , &y , &z);
            dist[x][y] = dist[y][x] = z;
        }
        floyd();
        spfa();
        int sum = INF;
        for(i = 0; i <= k; i++)
            sum = min(sum , d[1][i]);
        printf("%d\n" , sum);
    }
    return 0;
}

uva 10269 最短路+dp,布布扣,bubuko.com

时间: 2024-08-08 09:41:24

uva 10269 最短路+dp的相关文章

UVA - 10917 Walk Through the Forest (最短路+DP)

题意:Jimmy打算每天沿着一条不同的路走,而且,他只能沿着满足如下条件的道路(A,B):存在一条从B出发回家的路径,比所有从A出发回家的路径都短,你的任务是计算有多少条不同的路径 从后往前找最短路, 对于每一步要更新之后走的位置值: #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<algorithm> using namespace s

UVA 116 Unidirectional TSP(DP最短路字典序)

Description  Unidirectional TSP  Background Problems that require minimum paths through some domain appear in many different areas of computer science. For example, one of the constraints in VLSI routing problems is minimizing wire length. The Travel

uva 10671 - Grid Speed(dp)

题目链接:uva 10671 - Grid Speed 题目大意:给出N,表示在一个N*N的网格中,每段路长L,现在给出h,v的限制速度,以及起始位置sx,sy,终止位置ex,ey,时间范围st,et,车只走最短路,问说在范围内最快到达和耗油量最小的情况下时间和耗油量. 解题思路:dp[x][y][t]表示在x,y这一点,时间为t的耗油量最小为dp[x][y][t],vis[x][y][t]表示该情况是否可达.dx,dy表示由起点向终点移动的方向.因为时间为L?60v, 因为v是5的倍数,并且小

[UVA 12589]Learning Vector[DP]

题目链接:[UVA 12589]Learning Vector[DP] 题意分析:给出n个矢量,从中选择k个,以坐标原点为起点,收尾相连,问:这样的k个周围相连矢量与x轴围成图形的最大面积的两倍是多少? 解题思路:考虑状态:dp[id][pick][h]代表到第id个矢量为止,选择pick个矢量离最大面积还差多少,h为当前图形最右端高度.具体转移看代码. 这里着重说一下为什么要对这些矢量按斜率进行排序: 首先,整个求解过程其实就是在暴力枚举这些向量的组合,只不过采用了记忆化搜索优化. 其次,对于

Uva 12018 Juice Extractor dp

题目链接:点击打开链接 题意: 切水果游戏 给出n个水果 水果出现在屏幕上的时间的区间 1.每次切会把屏幕上所有水果切完 2.当同时切3个或以上时计分,分数为切的水果个数 3.不能遗漏水果 问最高得分 dp[i] 表示 最后一次切第i个的得分. #include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> using namespace std; #define N 1

uva 11578 - Situp Benches(dp+输出路径)

题目连接:uva 11578 - Situp Benches 题目大意:健身房有两个仪器,初始角度为10度,每次有人使用需要交15元,每调10度需要花费10元,现在有n个人,给出每个人使用仪器的顺序和角度,保证不会同时有大于2个人序号一样,求最小花费,并且输出每个人分别使用哪一个仪器,并且所有人使用结束后,要将仪器调回10度. 解题思路:dp[i][x][y]表示第i个人,一个仪器为x,另一个仪器为y的情况,path[i][x][y]记录的是它的前一个状态,[0]为前一个仪器的夹角,[1]为另一

UVA 1559 - Nim(博弈dp)

UVA 1559 - Nim 题目链接 题意:一开始有s个石子,2n个人轮流取石子,每个人有个最大能取数目,2n个人奇数一队,偶数一队,取到最后一个石子的队输,问谁赢 思路:记忆化搜索,每个人取的时候对应的后继状态如果有一个必败态,则该状态为必胜态,如果都是必胜态,则该状态为必败态 代码: #include <stdio.h> #include <string.h> int n, s, m[25], dp[25][10005]; int dfs(int now, int state

uva 1379 - Pitcher Rotation(dp)

题目链接:uva 1379 - Pitcher Rotation 题目大意:给出n,表示由n个人组成的战队,接着是m,表示有m个敌人,g表示要比赛的天数,给出g后,比赛的天数起始是g+10,然后是一个m*n的矩阵,g[i][j]表示第j个敌人被i打败后,战队所得到的分数.然后g+10个数,表示每天需要挑战的敌人是谁,0代表说休息:每个人出战的次数没有限制,但是比过一场后要休息4天,问说战队的最高得分. 解题思路:注意题目中的一点,说每个人比完一场赛后要休息4天,那么也就是说对于每个敌人来说,被派

UVa 10817 (状压DP + 记忆化搜索) Headmaster&#39;s Headache

题意: 一共有s(s ≤ 8)门课程,有m个在职教师,n个求职教师. 每个教师有各自的工资要求,还有他能教授的课程,可以是一门或者多门. 要求在职教师不能辞退,问如何录用应聘者,才能使得每门课只少有两个老师教而且使得总工资最少. 分析: 因为s很小,所以可以用状态压缩. dp(i, s1, s2)表示考虑了前i个人,有一个人教的课程的集合为s1,至少有两个人教的集合为s2. 在递归的过程中,还有个参数s0,表示还没有人教的科目的集合. 其中m0, m1, s0, s1, s2的计算用到位运算,还