CodeForces 507E Breaking Good(最短路)
来源:互联网 发布:淘宝wap访客是什么意思 编辑:程序博客网 时间:2024/05/20 03:07
题意:有n个点,m条边,你需要从1-n使得路径长度最短,并且走过的坏路要修,没走到的好路要炸,在最短路径的前提下使得需要的工程量最小。
思路:dp[i]表示到i点需要的工程量,dp[1]=所有的好路数目,中途经过一个好的要-1,经过一个坏的要+1,Dijkstra来确保是最短路径。
其实这道题并不是很难, 就是在最短路上加上求一个影响值, 但是这道题我做了三天才做出来,我也是无语了, 想想我的错误有三, 路径打印, 控制输出, 标记数组的大小。 好在我都把弄明白了, 也不算亏了, 详细的解说都在代码中。#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>#include<queue>using namespace std;const int maxn = 100000 + 10;//存边结构体struct Edge{ int from, to, z;};struct HeapNode{ int u, d; bool operator < (const HeapNode& rhs) const { return d > rhs.d; }};int d[maxn], p[maxn], F[maxn], vis[2 * maxn]; // vis数组为对边位置编号的标记数组,切记在无向图中vis的大小要为边数的二倍int n, m, sum;bool done[maxn]; //标记顶点是否计算过vector<int> G[maxn]; //存放边在edages中的位置vector<Edge> edges; //存放边//初始化函数void inin() { memset(vis, 0, sizeof(vis)); memset(done, 0, sizeof(done)); memset(d, 99, sizeof(d)); memset(F, 0, sizeof(F)); for(int i = 0; i <= n; i++) G[i].clear(); edges.clear(); sum = 0;}//存边的函数 注意无向图中要调用两次void AddEdge(int from, int to, int z) { edges.push_back((Edge){from, to, z}); int k = edges.size(); G[from].push_back(k-1); if(z) sum++;}//求最短路void Dijkstra(int s){ priority_queue<HeapNode> q; d[s] = 0; F[s] = sum/2; p[s] = -1; //打印路径时,结束的标记,应与选数据中的第一条边区别开,第一条在图中存的位置编号为零,故不能为零, q.push((HeapNode){s, 0}); while(!q.empty()) { HeapNode x = q.top(); q.pop(); int u = x.u; if(done[u]) continue; done[u] = true; for(int i = 0; i < G[u].size(); i++) { Edge e = edges[G[u][i]]; if(d[e.to] > d[u]+1) { d[e.to] = d[u] + 1; if(e.z) F[e.to] = F[u] - 1; else F[e.to] = F[u] + 1; p[e.to] = G[u][i]; q.push((HeapNode){e.to, d[e.to]}); } else if(d[e.to] == d[u]+1) { int k ; if(e.z) k = F[u] - 1; else k = F[u] + 1; if(F[e.to] > k) { F[e.to] = k; p[e.to] = G[u][i]; } } } }}//求路径void bfs(int n){ if(n == -1) return ; vis[n] = 1; bfs(p[edges[n].from]);}int main(){ int x, y, z; while(~scanf("%d%d", &n, &m)) { inin(); for(int i = 0; i < m; i++) { scanf("%d%d%d", &x, &y, &z); AddEdge(x, y, z); AddEdge(y, x, z); } Dijkstra(1); bfs(p[n]);/* 循环求路径 int pre = n; while(p[pre] != -1) { vis[p[pre]] = 1; pre = edges[p[pre]].from; }*/ printf("%d\n", F[n]); for(int i = 0; i < 2*m; i+=2) if((vis[i]||vis[i+1]) && !edges[i].z) printf("%d %d 1\n", edges[i].from, edges[i].to); else if(!vis[i] && !vis[i+1] && edges[i].z) printf("%d %d 0\n", edges[i].from, edges[i].to); } return 0;}
0 0
- CodeForces 507E Breaking Good 最短路
- CodeForces 507E Breaking Good(最短路)
- CodeForces 507E Breaking Good(最短路)
- 最短路Codeforces E. Breaking Good
- codeforces 287DIV2 E - Breaking Good(最短路)
- cf 507E Breaking Good 最短路
- Codeforces Round #287 (Div. 2) E. Breaking Good 最短路
- Codeforces 507E Breaking Good【最短路SPFA+Dp+记录路径】好题~~~
- Codeforces Round #287 (Div. 2) E. Breaking Good(最短路、dp)
- Codeforces Round #287 (Div. 2) E. Breaking Good(最短路、dp)
- 507E Breaking Good (最短路+记录路径)
- Breaking Good - CodeForces 507E
- Codeforces Round #287 (Div. 2) 507E E. Breaking Good
- Codeforces Round #287 (Div. 2) 507 E. Breaking Good
- 【CF 507E】Breaking Good
- Codeforces 509E. Breaking Good SPFA
- E. Breaking Good
- Codeforces Round #287 (Div. 2) E. Breaking Good
- Hacking Vim: startify(05)
- 欢迎使用CSDN-markdown编辑器
- Xamarin.Forms探索--使用 Xamarin.Forms 来创建跨平台的用户界面
- QPS 与 TPS 简介
- 多级ztree
- CodeForces 507E Breaking Good(最短路)
- Android开源项目分类汇总
- strftime、strptime和stime的使用
- git的使用方法
- Hacking Vim: bookmarks(06)
- 珍爱生命,使用python
- 纯虚函数
- Extjs视频教程_Extjs5.0从入门到实战开发信息管理系统
- Hacking Vim: UltiSnips(07)