[Codeforces 507E] Breaking Good
[题目链接]
https://codeforces.com/contest/507/problem/E
[算法]
首先BFS求出1到其余点的最短路 , N到其余点的最短路,记为distA[]和distB[]
显然 , 我们只需最大化求出的最短路上没有被破坏的边即可 , 不妨用f[i]表示现在在城市i , distA[i] + distB[i] = distA[N] , 最多还能经过几条没有被破坏的边
记忆化搜索即可
时间复杂度 : O(N)
[代码]
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + ;
const int inf = 1e9; struct edge
{
int to , state , id , nxt;
} e[MAXN << ];
struct info
{
int u , v , ns;
} res[MAXN]; int n , m , tot;
int u[MAXN],v[MAXN],state[MAXN],head[MAXN],dista[MAXN],distb[MAXN],f[MAXN];
pair<int,int> nxt[MAXN];
bool visited[MAXN]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void addedge(int u,int v,int s,int id)
{
tot++;
e[tot] = (edge){v,s,id,head[u]};
head[u] = tot;
}
inline void bfs1(int s)
{
queue< int > q;
dista[s] = ;
visited[s] = true;
q.push(s);
while (!q.empty())
{
int cur = q.front();
q.pop();
for (int i = head[cur]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!visited[v])
{
visited[v] = true;
dista[v] = dista[cur] + ;
q.push(v);
}
}
}
}
inline void bfs2(int s)
{
queue< int > q;
distb[s] = ;
visited[s] = true;
q.push(s);
while (!q.empty())
{
int cur = q.front();
q.pop();
for (int i = head[cur]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!visited[v])
{
visited[v] = true;
distb[v] = distb[cur] + ;
q.push(v);
}
}
}
}
inline int dp(int u)
{
if (u == n) return f[u] = ;
if (f[u] != -) return f[u];
f[u] = -inf;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to , st = e[i].state , id = e[i].id , value;
if (dista[u] + distb[v] + != dista[n]) continue;
if (st == )
{
value = dp(v) + ;
if (value > f[u])
{
f[u] = value;
nxt[u] = make_pair(v,id);
}
} else
{
value = dp(v);
if (value > f[u])
{
f[u] = value;
nxt[u] = make_pair(v,id);
}
}
}
return f[u];
}
inline void getpath(vector<int> &a)
{
int now = ;
while (nxt[now].first)
{
a.push_back(nxt[now].second);
now = nxt[now].first;
}
} int main()
{ read(n); read(m);
for (int i = ; i <= m; i++)
{
read(u[i]); read(v[i]); read(state[i]);
addedge(u[i],v[i],state[i],i);
addedge(v[i],u[i],state[i],i);
}
memset(visited,false,sizeof(visited));
bfs1();
memset(visited,false,sizeof(visited));
bfs2(n);
memset(f,,sizeof(f));
dp();
vector<int> path;
getpath(path);
int len = ;
memset(visited,false,sizeof(visited));
for (unsigned i = ; i < path.size(); i++)
{
visited[path[i]] = true;
if (state[path[i]] == ) res[++len] = (info){u[path[i]],v[path[i]],};
}
for (int i = ; i <= m; i++)
{
if (!visited[i] && state[i])
res[++len] = (info){u[i],v[i],};
}
printf("%d\n",len);
for (int i = ; i <= len; i++) printf("%d %d %d\n",res[i].u,res[i].v,res[i].ns); return ; }
[Codeforces 507E] Breaking Good的更多相关文章
- CodeForces 507E Breaking Good 2维权重dij
Breaking Good 题解: 2维权重dij, 先距离最短, 后改变最小. 在这个题中, 如果要改变最小, 则让更多的可用边放进来. 然后可以用pre存下关键边. 代码: ...
- 【codeforces 507E】Breaking Good
[题目链接]:https://vjudge.net/contest/164884#problem/D [题意] 给你一张图; 图中有些路是完好的;但有些路还没修好; 先不管路有没有修好; 问你从起点到 ...
- cf 507E. Breaking Good
因为要求是在保证最短路的情况下花费是最小的,所以(先保证最短路设为S吧) 那么花费就是最短路上的新建边条数A+剩余拆掉边的条数B,而且总的原有好的边是一定的,所以,只要使得A尽量小,那么B就大,所以要 ...
- Codeforces Round #287 (Div. 2) E. Breaking Good 最短路
题目链接: http://codeforces.com/problemset/problem/507/E E. Breaking Good time limit per test2 secondsme ...
- Codeforces Round #287 (Div. 2) E. Breaking Good [Dijkstra 最短路 优先队列]
传送门 E. Breaking Good time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- Codeforces Round #287 (Div. 2) E. Breaking Good 路径记录!!!+最短路+堆优化
E. Breaking Good time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- Codeforces Breaking Good
Breaking Good time limit per test 2 seconds memory limit per test 256 megabytes Breaking Good is a n ...
- Doors Breaking and Repairing CodeForces - 1102C (思维)
You are policeman and you are playing a game with Slavik. The game is turn-based and each turn consi ...
- Codeforces Round #531 (Div. 3) C. Doors Breaking and Repairing (博弈)
题意:有\(n\)扇门,你每次可以攻击某个门,使其hp减少\(x\)(\(\le 0\)后就不可修复了),之后警察会修复某个门,使其hp增加\(y\),问你最多可以破坏多少扇门? 题解:首先如果\(x ...
随机推荐
- [Kubernetes]集群配置免密登录Permission denied (publickey,password) 解决办法
在用ansible部署Kubernetes集群是需要配置免密登录,但是遇到Permission denied (publickey,password)的问题 首先推断可能是sshd_config的配置 ...
- Leetcode39.Combination Sum组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制重复被选 ...
- [HDU2896]病毒侵袭(AC自动机)
传送门 题目中文描述,赞! 除了val记录id以外就是模板. 注意:每次数组都要清0.0 ——代码 #include <cstdio> #include <queue> #in ...
- hdu 2181暴搜
#include<stdio.h> #include<string.h> #define N 30 int map[N][4],total; void dfs(int n,in ...
- bzoj 2326 矩阵乘法
[HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2415 Solved: 1413[Submit][Status][Di ...
- CDQ分治模板
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #defi ...
- Android基本动画
Android基本动画 Android Animations动画使用详解 一.动画类型 Android的animation由四种类型组成:alpha.scale.translate.rotate XM ...
- msp430入门编程17
msp430中C语言的寄存器操作 msp430入门学习 msp430入门编程
- Codeforces 653A Bear and Three Balls【水题】
题目链接: http://codeforces.com/problemset/problem/653/A 题意: 给定序列,找是否存在连续的三个数. 分析: 排序~去重~直接判断~~ 代码: #inc ...
- 洛谷——P3119 [USACO15JAN]草鉴定Grass Cownoisseur
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...