[题目链接]

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的更多相关文章

  1. CodeForces 507E Breaking Good 2维权重dij

    Breaking Good 题解:         2维权重dij, 先距离最短, 后改变最小.   在这个题中, 如果要改变最小, 则让更多的可用边放进来. 然后可以用pre存下关键边.   代码: ...

  2. 【codeforces 507E】Breaking Good

    [题目链接]:https://vjudge.net/contest/164884#problem/D [题意] 给你一张图; 图中有些路是完好的;但有些路还没修好; 先不管路有没有修好; 问你从起点到 ...

  3. cf 507E. Breaking Good

    因为要求是在保证最短路的情况下花费是最小的,所以(先保证最短路设为S吧) 那么花费就是最短路上的新建边条数A+剩余拆掉边的条数B,而且总的原有好的边是一定的,所以,只要使得A尽量小,那么B就大,所以要 ...

  4. Codeforces Round #287 (Div. 2) E. Breaking Good 最短路

    题目链接: http://codeforces.com/problemset/problem/507/E E. Breaking Good time limit per test2 secondsme ...

  5. 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 ...

  6. 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 ...

  7. Codeforces Breaking Good

    Breaking Good time limit per test 2 seconds memory limit per test 256 megabytes Breaking Good is a n ...

  8. 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 ...

  9. Codeforces Round #531 (Div. 3) C. Doors Breaking and Repairing (博弈)

    题意:有\(n\)扇门,你每次可以攻击某个门,使其hp减少\(x\)(\(\le 0\)后就不可修复了),之后警察会修复某个门,使其hp增加\(y\),问你最多可以破坏多少扇门? 题解:首先如果\(x ...

随机推荐

  1. [codeforces722C]Destroying Array

    [codeforces722C]Destroying Array 试题描述 You are given an array consisting of n non-negative integers a ...

  2. 【BZOJ4517】排列计数(排列组合)

    题意:1-n的一个序列,其中有m个a[i]=i,求方案数 n,m<=1000000 题意:显然ANS=c(n,m)*d[n-m] d[i]为错排方案数=d[i-1]*n+(-1)^n ; ..] ...

  3. 转 蓝桥杯 历届试题 波动数列 [ dp ]

    传送门   历届试题 波动数列   时间限制:1.0s   内存限制:256.0MB     锦囊1   锦囊2   锦囊3   问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个 ...

  4. hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]

    传送门 DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131 ...

  5. POJ 3254 【状态压缩DP】

    题意: 给一块n*m的田地,1代表肥沃,0代表贫瘠. 现在要求在肥沃的土地上种草,要求任何两个草都不能相邻. 问一共有多少种种草的方法. 种0棵草也是其中的一种方法. n和m都不大于12. 思路: 状 ...

  6. 初学总结--------Java修饰符与修饰关键字(且叫修饰关键字)

    Java中有类,有成员变量,有成员方法,有局部变量.他们分别能用什么来修饰? 目前学习到的类,有普通类和内部类. 一.修饰普通类: 1.public  每个文件中只有一个类能被public修饰,表示可 ...

  7. 关于MySQL的boolean和tinyint(1)

    原文:http://blog.csdn.net/woshixuye/article/details/7089508 MySQL保存boolean值时用1代表TRUE,0代表FALSE.boolean在 ...

  8. maven的超级pom

    对于 Maven3,超级 POM 在文件 %MAVEN_HOME%/lib/maven-model-builder-x.x.x.jar 中的 org/apache/maven/model/pom-4. ...

  9. Office EXCEL 创建图片超链接打不开怎么办 Excel打开图片提示发生了意外错误怎么办

    如下图所示,点击超链接提示无法打开指定的文件   如果使用Office打开,则提示发生了意外错误   你需要先把IE浏览器打开,这样就可以打开了,并非是图像的相对位置不正确导致的.      

  10. composer-安装laravel

    laravel文档地址: https://docs.golaravel.com/docs/5.6/installation/ 我们怎么将Apache和PHP互联起来呢? http://www.cnbl ...