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 ...
随机推荐
- ssi技术
html页面 <!DOCTYPE html> <html> <head> <title>测试ssi</title> <meta nam ...
- R获取股票数据
R中好几个Pkg都提供了股票数据的在线下载方法,如果非得在其中找出一个最好的,那么quantmod当之无愧!举一个例子,譬如下载沪市大盘数据,代码可以是: library(quantmod)SSE & ...
- [百度地图] MultiZMap 修改使用;
MultiZMap修改说明 MultiZMap 是基于百度地图API 封装的一些常用功能类库:主要以prototype方式实现:并且实现了一些辅助的功能,比如添加 Marker 功能,事件管理等: 以 ...
- 基础知识系列☞C#中数组Array、ArrayList和List三者的区别
数组() #region 数组 //初始化方式_0:先声明再赋值 ]; weekDays_0[] = "Sun"; weekDays_0[] = "Mon"; ...
- R语言 奇怪的NA
> 1+NA [1] NA > NA==1 [1] NA > c(NA,1:50) [1] NA 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
- sublime linux下无法输入中文
cd ~ vim sublime_imfix.c 输入 #include <gtk/gtkimcontext.h> void gtk_im_context_set_client_windo ...
- CSS中font-size、font-family、line-height顺序以及简写属性
顺序: font-size line-height font-family body { font-size: 12px}; h1 { font: bold 200%/1.2 ...
- 自定义Listview
public class MyListView extends ListView { public MyListView(Context context) { super(context); } pu ...
- java中线程分两种,守护线程和用户线程。
java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...
- IntelliJ中的main函数和System.out.println()快捷键
1.在IntelJ中和Eclipse中稍有不同,在Eclipse中,输入main再按Alt+/即可自动补全main函数,但是在IntellJ中则是输入psvm,选中即可 2.在方法体内部有for循环, ...