ACM/ICPC 之 最短路-Floyd+SPFA(BFS)+DP(ZOJ1232)

这是一道非常好的题目,融合了很多知识点。



ZOJ1232-Adventrue of Super Mario

  这一题折磨我挺长时间的,不过最后做出来非常开心啊,哇咔咔咔

  题意就不累述了,注释有写,难点在于状态转移方程的确立和SPFA的过程

  1 //最短路:Floyd+SPFA(BFS)+DP
  2 //Time:20Ms    Memory:336K
  3 //题目很好,数据较弱,网上部分代码有些问题却能够A掉
  4 //题意:超级马里奥要从A+B处背着公主以最短路程到达1处,其中1-A是村庄,剩下的是城堡
  5 //        有可使用K次可飞过L长的靴子(每次都以结点开始或结束),求最短路长
  6 //首先需要得到任意两点之间的最短路-Floyd较为简便(10^5次操作也能接受)
  7 //其次需要利用BFS从A+B处开始遍历并进行状态转移-BFS+DP
  8 //构造状态:DP[i][k]:从i到A+B经过k次瞬移得到的最短路
  9 //状态转移方程:
 10 //能够从x瞬移到y:dp[x][k] = min(dp[x][k], dp[y][k - 1], dp[y][k] + d[x][y])
 11 //不能从x瞬移到y:dp[x][k] = min(dp[x][k], dp[y][k] + d[x][y])
 12 #include<iostream>
 13 #include<cstring>
 14 #include<cstdio>
 15 #include<algorithm>
 16 #include<queue>
 17 #include<vector>
 18 using namespace std;
 19
 20 #define INF 0x3f3f3f3f
 21 #define MAX 105
 22
 23 vector<int> e[MAX];    //邻接表
 24 int A, B, M, L, K;
 25 int d[MAX][MAX];    //distance
 26 bool fly[MAX][MAX];    //能否瞬移
 27 int vis[MAX];
 28 int dp[MAX][12];    //dp[i][k]:从i到A+B经过k次瞬移得到的最短路
 29
 30 void floyd(int N)
 31 {
 32     for (int i = 1; i <= N; i++)
 33         d[i][i] = 0;
 34     for (int k = 1; k <= N; k++)
 35         for (int i = 1; i <= N; i++)
 36             for (int j = 1; j <= N; j++)
 37                 if (d[i][j] > d[i][k] + d[k][j])
 38                 {
 39                     d[i][j] = d[i][k] + d[k][j];
 40                     if (k <= A && d[i][j] <= L)
 41                     {
 42                         fly[i][j] = true;
 43                         e[i].push_back(j);
 44                     }
 45                 }
 46 }
 47
 48 int main()
 49 {
 50     //freopen("in.txt", "r", stdin);
 51     //freopen("out-2.txt", "w", stdout);
 52     int T;
 53     scanf("%d", &T);
 54     while (T--) {
 55         memset(d, INF, sizeof(d));
 56         memset(fly, false, sizeof(fly));
 57         memset(e, 0, sizeof(e));
 58         scanf("%d%d%d%d%d", &A, &B, &M, &L, &K);
 59         while (M--) {
 60             int u, v, w;
 61             scanf("%d%d%d", &u, &v, &w);
 62             d[v][u] = d[u][v] = w;
 63             e[v].push_back(u);
 64             e[u].push_back(v);
 65             if (w <= L)    fly[u][v] = fly[v][u] = true;
 66         }
 67
 68         floyd(A + B);
 69         //类似SPFA的过程(BFS)
 70         memset(dp, INF, sizeof(dp));
 71         for (int i = 1; i <= K; i++)
 72             dp[A + B][i] = 0;
 73         for (int i = 1; i <= A + B; i++)
 74             dp[i][0] = d[i][A + B];
 75         for (int k = 1; k <= K; k++)
 76         {
 77             memset(vis, false, sizeof(vis));
 78             queue<int> q;
 79             q.push(A + B);    //从A+B开始遍历
 80             vis[A + B] = true;
 81             while (!q.empty()) {
 82                 int cur = q.front();
 83                 q.pop();
 84                 for (int i = 0; i < e[cur].size(); i++)
 85                 {
 86                     int u = e[cur][i];
 87                     int tmp = dp[u][k];
 88                     //状态转移
 89                     if (fly[u][cur])    //可瞬移
 90                         dp[u][k] = min(dp[u][k], dp[cur][k - 1]);
 91                     dp[u][k] = min(dp[u][k], dp[cur][k] + d[cur][u]);
 92                     //需要转移状态的条件 - 没有访问过 or 最短路长变更
 93                     if (!vis[u] || tmp != dp[u][k])
 94                         q.push(u);
 95                     vis[u] = true;
 96                 }
 97             }
 98         }
 99         printf("%d\n", dp[1][K]);
100     }
101     return 0;
102 }
时间: 2024-08-13 11:11:30

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/132768 K (Java/Others)Total Submission(s): 1496    Accepted Submission(s): 723 Problem Description Kelukin is a businessman. Every day, he travels arou

ACM/ICPC 之 最短路-SPFA+正逆邻接表(POJ1511(ZOJ2008))

求单源最短路到其余各点,然后返回源点的总最短路长,以构造邻接表的方法不同分为两种解法. POJ1511(ZOJ2008)-Invitation Cards 改变构造邻接表的方法后,分为两种解法 解法一: 1 //POJ1511-ZOJ2008 2 //Time:7766Ms Memory:99112K 3 //求从1处到各点后再返回1处的最短总路长 4 //需要构造邻接表和逆邻接表 5 //构造方法1:vector构造邻接表 6 //SPFA+邻接表 7 #include<iostream>

ACM/ICPC 之 靠墙走-DFS+BFS(POJ3083)

//POJ3083 //DFS求靠左墙(右墙)走的路径长+BFS求最短路 //Time:0Ms Memory:716K #include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; #define MAX 45 #define INRANGE(x,y) (x >= 0 && x < n && y

hdu5045||2014 ACM/ICPC Asia Regional Shanghai Online【数位dp】

大意:有n道题m个熊孩子,每个熊孩子对于每个题的正确率是已知的,对于每一道题必须有且只有一个熊孩子去做, 并且在任意时刻任意两个熊孩子的做的题数之差都不能大于等于2 比如有5个题三个熊孩子 那么1 2 3 3 1是合法的 但是12231是不合法的 求的是最大期望 分析: 题目已知熊孩子的数目最多是十个那么我们可以将其压缩成2进制(1024) dp[i][j]表示对于前i道题,状态为j的最大概率 那么&运算和|运算就能很好的处理这个问题 对于(1<<n - 1) 要将其清空 代码: 1

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 Submission(s): 997    Accepted Submission(s): 306 Problem Description The empire is under attack again. The general of empire is planning to defend his

ACM-最短路(SPFA,Dijkstra,Floyd)之最短路——hdu2544

***************************************转载请注明出处:http://blog.csdn.net/lttree*************************************** 最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 28761    Accepted Submissio

HDU - 2544 - 最短路 (最基础单源最短路问题!!dijkstra+floyd+SPFA)

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 34617    Accepted Submission(s): 15001 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找

ACM/ICPC 之 数据结构-邻接表+BFS(TshingHua OJ-无线广播Broadcast)

这道题中若能够构成互不干扰的区域,其构成的图其实就是汉密尔顿路(Hamilton road),因此如果能够观察出来可以直接转化为汉密尔顿路的存在性证明,即便不能观察,我相信ACMer也能转化为BFS问题,这道题是一道很好的图论问题,对考察自己图论的基本功很有帮助. 无线广播(Broadcast) 描述 某广播公司要在一个地区架设无线广播发射装置.该地区共有n个小镇,每个小镇都要安装一台发射机并播放各自的节目. 不过,该公司只获得了FM104.2和FM98.6两个波段的授权,而使用同一波段的发射机

ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))

求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其到(1,1)的最短路长 题解:开始做的时候用BFS暴力做了一次,结果RE了,后来看了其他的题解和discuss才转向状态压缩.也看到有人用A*做出来了. 现在简要介绍一下状态压缩的思路: 由于蛇身最长只有8,可以利用两条相邻蛇身坐标确定其相对方向(四个方向),两位二进制可以表示 这样 一个蛇头坐标+