Codeforces Round #287 (Div. 2) E. Breaking Good(最短路、dp)
2016-02-13 17:24
696 查看
题意:
N≤105个城市,M≤105条边,保证无向图连通且无自环和重边
边分2种,0代表毁坏的,1代表正常的
现要1→n的最短路,且影响值最小,影响值:=最短路上的毁坏边数+不在最短路上的正常边数
输出影响值以及影响的边,状态为新的状态
分析:
设所有的正常边为ALL,最短路为D,最短路上的正常边为X
ans=D−X+ALL−X=D+ALL−2X,由于D和ALL都是常数,我们现在要X最大才能使ans最小
由于边权是1,最短路bfs就可以了,同时dp一下,g[i]:=以i结尾的最短路上最多的正常边数
记录下转移,方便打印路径即可
时间复杂度为O(n+m)
代码:
N≤105个城市,M≤105条边,保证无向图连通且无自环和重边
边分2种,0代表毁坏的,1代表正常的
现要1→n的最短路,且影响值最小,影响值:=最短路上的毁坏边数+不在最短路上的正常边数
输出影响值以及影响的边,状态为新的状态
分析:
设所有的正常边为ALL,最短路为D,最短路上的正常边为X
ans=D−X+ALL−X=D+ALL−2X,由于D和ALL都是常数,我们现在要X最大才能使ans最小
由于边权是1,最短路bfs就可以了,同时dp一下,g[i]:=以i结尾的最短路上最多的正常边数
记录下转移,方便打印路径即可
时间复杂度为O(n+m)
代码:
// // Created by TaoSama on 2016-02-13 // Copyright (c) 2016 TaoSama. All rights reserved. // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, m; struct Edge { int v, nxt, mark; } edge[N << 1]; int head , cnt; void addEdge(int u, int v, int mark) { edge[cnt] = (Edge) {v, head[u], mark}; head[u] = cnt++; } int f , g , pre ; void bfs() { queue<int> q; q.push(1); memset(f, 0x3f, sizeof f); memset(g, 0, sizeof g); f[1] = g[1] = 0; while(q.size()) { int u = q.front(); q.pop(); for(int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v, mark = edge[i].mark; if(f[v] == INF) { f[v] = f[u] + 1; g[v] = g[u] + mark; pre[v] = i; q.push(v); } else if(f[v] == f[u] + 1) { if(g[u] + mark > g[v]) { g[v] = g[u] + mark; pre[v] = i; } } } } } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%d", &n, &m) == 2) { cnt = 0; memset(head, -1, sizeof head); int all = 0; for(int i = 1; i <= m; ++i) { int u, v, mark; scanf("%d%d%d", &u, &v, &mark); all += mark; addEdge(u, v, mark); addEdge(v, u, mark); } bfs(); for(int u = n, id; u != 1; u = edge[id ^ 1].v) { id = pre[u]; if(edge[id].mark == 0) edge[id].mark = edge[id ^ 1].mark = 2; //to repair else edge[id].mark = edge[id ^ 1].mark = 0; //ignore } printf("%d\n", f + all - 2 * g ); for(int i = 0; i < cnt; i += 2) { if(!edge[i].mark) continue; printf("%d %d %d\n", edge[i ^ 1].v, edge[i].v, edge[i].mark - 1); } } return 0; }
相关文章推荐
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- Hdu2066(一个人的旅行)
- soj1005. Roll Playing Games
- 01背包问题
- LeetCode之Maximum Product Subarray