ACM/ICPC 之 最短路-Floyd+SPFA(BFS)+DP(ZOJ1232)
这是一道非常好的题目,融合了很多知识点。
ZOJ1232-Adventrue of Super Mario
这一题折磨我挺长时间的,不过最后做出来非常开心啊,哇咔咔咔
题意就不累述了,注释有写,难点在于状态转移方程的确立和SPFA的过程
//最短路:Floyd+SPFA(BFS)+DP
//Time:20Ms Memory:336K
//题目很好,数据较弱,网上部分代码有些问题却能够A掉
//题意:超级马里奥要从A+B处背着公主以最短路程到达1处,其中1-A是村庄,剩下的是城堡
// 有可使用K次可飞过L长的靴子(每次都以结点开始或结束),求最短路长
//首先需要得到任意两点之间的最短路-Floyd较为简便(10^5次操作也能接受)
//其次需要利用BFS从A+B处开始遍历并进行状态转移-BFS+DP
//构造状态:DP[i][k]:从i到A+B经过k次瞬移得到的最短路
//状态转移方程:
//能够从x瞬移到y:dp[x][k] = min(dp[x][k], dp[y][k - 1], dp[y][k] + d[x][y])
//不能从x瞬移到y:dp[x][k] = min(dp[x][k], dp[y][k] + d[x][y])
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std; #define INF 0x3f3f3f3f
#define MAX 105 vector<int> e[MAX]; //邻接表
int A, B, M, L, K;
int d[MAX][MAX]; //distance
bool fly[MAX][MAX]; //能否瞬移
int vis[MAX];
int dp[MAX][]; //dp[i][k]:从i到A+B经过k次瞬移得到的最短路 void floyd(int N)
{
for (int i = ; i <= N; i++)
d[i][i] = ;
for (int k = ; k <= N; k++)
for (int i = ; i <= N; i++)
for (int j = ; j <= N; j++)
if (d[i][j] > d[i][k] + d[k][j])
{
d[i][j] = d[i][k] + d[k][j];
if (k <= A && d[i][j] <= L)
{
fly[i][j] = true;
e[i].push_back(j);
}
}
} int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out-2.txt", "w", stdout);
int T;
scanf("%d", &T);
while (T--) {
memset(d, INF, sizeof(d));
memset(fly, false, sizeof(fly));
memset(e, , sizeof(e));
scanf("%d%d%d%d%d", &A, &B, &M, &L, &K);
while (M--) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
d[v][u] = d[u][v] = w;
e[v].push_back(u);
e[u].push_back(v);
if (w <= L) fly[u][v] = fly[v][u] = true;
} floyd(A + B);
//类似SPFA的过程(BFS)
memset(dp, INF, sizeof(dp));
for (int i = ; i <= K; i++)
dp[A + B][i] = ;
for (int i = ; i <= A + B; i++)
dp[i][] = d[i][A + B];
for (int k = ; k <= K; k++)
{
memset(vis, false, sizeof(vis));
queue<int> q;
q.push(A + B); //从A+B开始遍历
vis[A + B] = true;
while (!q.empty()) {
int cur = q.front();
q.pop();
for (int i = ; i < e[cur].size(); i++)
{
int u = e[cur][i];
int tmp = dp[u][k];
//状态转移
if (fly[u][cur]) //可瞬移
dp[u][k] = min(dp[u][k], dp[cur][k - ]);
dp[u][k] = min(dp[u][k], dp[cur][k] + d[cur][u]);
//需要转移状态的条件 - 没有访问过 or 最短路长变更
if (!vis[u] || tmp != dp[u][k])
q.push(u);
vis[u] = true;
}
}
}
printf("%d\n", dp[][K]);
}
return ;
}
ACM/ICPC 之 最短路-Floyd+SPFA(BFS)+DP(ZOJ1232)的更多相关文章
- 2017 ACM/ICPC Asia Regional Shenyang Online spfa+最长路
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- 【ACM程序设计】求短路 Floyd算法
最短路 floyd算法 floyd是一个基于贪心思维和动态规划思维的计算所有点到所有点的最短距离的算法. P57-图-8.Floyd算法_哔哩哔哩_bilibili 对于每个顶点v,和任一顶点对(i, ...
- ACM/ICPC 之 最短路-SPFA+正逆邻接表(POJ1511(ZOJ2008))
求单源最短路到其余各点,然后返回源点的总最短路长,以构造邻接表的方法不同分为两种解法. POJ1511(ZOJ2008)-Invitation Cards 改变构造邻接表的方法后,分为两种解法 解法一 ...
- ACM/ICPC 之 靠墙走-DFS+BFS(POJ3083)
//POJ3083 //DFS求靠左墙(右墙)走的路径长+BFS求最短路 //Time:0Ms Memory:716K #include<iostream> #include<cst ...
- hdu 4460 第37届ACM/ICPC杭州赛区H题 STL+bfs
题意:一些小伙伴之间有朋友关系,比如a和b是朋友,b和c是朋友,a和c不是朋友,则a和c之间存在朋友链,且大小为2,给出一些关系,求出这些关系中最大的链是多少? 求最短路的最大距离 #include& ...
- ACM/ICPC 之 一道不太简单的DP面试题(Geeksforgeeks)
题面来源:geeksforgeeks/1993 题解:geeksforgeeks 题目简述:给一个m*n的矩阵,计算从(1,1)到(m,n)的所有不回退路径中,经过k次转向后的路径有多少条 输入T个样 ...
- 2013 ACM/ICPC Asia Regional Changsha Online - G(DP)
第一眼就想到DP,然后想了N久就想不到可以不重算的DP 最后没办法了 先算出来 再去重.. 因为最多只有三个 对于三个来说有三种组合情况 x+y+z, x*y*z, x*y+z 那要么 x,y,z都 ...
- HDU 5876 Sparse Graph 【补图最短路 BFS】(2016 ACM/ICPC Asia Regional Dalian Online)
Sparse Graph Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)To ...
- HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)
Barricade Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
随机推荐
- GOF业务场景的设计模式-----设计模式六大原则
单一职责原则(Single Responsibility Principle) 定义:不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责. 问题由来:类T负责两个不同的职责:职责P1, ...
- 处理dataTable的行和列数据
DataTable dt = null; foreach (DataRow dr in dt.Rows) { ; j < dr.ItemArray.Length; j++) { tempColu ...
- GCD与NSOperationQueue
1> GCD是纯C语言的API,NSOperationQueue是基于GCD的OC版本封装 2> GCD只支持FIFO(先入先出)的队列,NSOperationQueue可以很方便地调整执 ...
- 面试集锦-常量,const, const 对指针的影响
在C语言中不可改变的数据(量)就是常量 在C语言中有三种常量 字面量(直接量),就是直接写出来的,从写法上就可以看出值与类型等,例如:19,123.456等 名字常量 ...
- 繁华模拟赛day8 科技树
/* 贪心,很明显是越容易升级的越先升级 */ #include<iostream> #include<cstdio> #include<string> #incl ...
- 第一个C++例子
#include <iostream> using namespace std; class Time { private: int hour; int minute; int secon ...
- PHP读取excel文档
PHP读取excel文档 项目需要读取Excel的内容,从百度搜索了下,主要有两个选择,第一个是PHPExcelReader,另外一个是PHPExcel. PHPExcelReader比较轻量级, ...
- Linux 信号量大全
编号 信号名称 缺省动作 说明 1 SIGHUP 终止 终止控制终端或进程 2 SIGINT 终止 键盘产生的中断(Ctrl-C) 3 SIGQUIT dump 键盘产生的退出 4 SIGILL du ...
- 校友聊NABCD
特点之一 界面简洁 N:软件的界面是软件成功的必要条件,界面简洁,用户使用方便,就会吸引用户. A:界面可用多种做法做,暂定用C# B:简洁的界面,用户易于理解各项功能,方便使用. C:没有其 ...
- 百度定位API报错:leaked ServiceConnection com.baidu.location.LocationClient$1@426122f0
使用百度MapApi定位时候,当退出当时使用的activity后,则会报如题的异常,解决办法: 1:当退出当前定位的activity时,一定要在onDestroy方法中要mLocClient.stop ...