[题目链接]

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. 两个很实用很方便的函数核心及用法{(lower_bound)+(max_element))~~

    (1)            关于 lower_bound(a,a+n,x)-a的用法:                                                求x在数组a中的 ...

  2. 【优先级队列】Southwestern Europe Regional Contest Canvas Painting

    https://vjudge.net/contest/174235#problem/D [题意] 给定n个已知size的帆布,要给这n块帆布涂上不同的颜色,规则是这样的: 每次选择一种颜色C 对于颜色 ...

  3. [转]maven编译时出现读取XXX时出错invalid LOC header (bad signature)

    maven编译时出现读取XXX时出错invalid LOC header (bad signature) 一.发现问题右击pom.xml,run as —> maven install,会看到c ...

  4. C#中对字符串的加密和解密

    加密: /// <summary> /// 对字符串进行加密 /// </summary> /// <param name="proclaimText" ...

  5. msp430入门编程21

    msp430中C语言的扩展--#pragma编译命令

  6. Linux中的进程与线程

    介绍了Linux下fork()创建进程以及使用pthread_create()创建线程的方法 1. 基于进程的斐波那契数列 在下面的代码中,由子进程进行斐波那契数列的输出,父进程要等待子进程输出完毕, ...

  7. python学习之-- mysql模块和sqlalchemy模块

    简单介绍python下操作mysql数据库模块有2个:pyhton-mysqldb  和 pymysql 说明:在python3中支持mysql 的模块已经使用pymysql替代了MysqlDB(这个 ...

  8. python学习之- 生成器/迭代器

    列表生成式写法: [ i*2 for i in range(10) ]也可以带函数 [ fun(i) for i in range(10) ] 生成器:一边循环一边计算的机制称为生成器.在常用函数中, ...

  9. [洛谷U22158]策划体验(树上斜率优化)(二分最优决策)

    题目背景 OL不在,Clao又在肝少*前线,他虽然觉得这个游戏的地图很烦,但是他认为地图的难度还是太低了,习习中作为策划还不够FM,于是他自己YY了一种新的地图和新的机制: 题目描述 整个地图呈树形结 ...

  10. 仿苹果app下载动画-煎饼

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...