Codeforces Breaking Good
Breaking Good
time limit per test 2 seconds
memory limit per test 256 megabytes
Breaking Good is a new video game which a lot of gamers want to have. There is a certain level in the game that is really difficult even for experienced gamers.
Walter William, the main character of the game, wants to join a gang called Los Hermanos (The Brothers). The gang controls the whole country which consists of n cities with m bidirectional roads connecting them. There is no road is connecting a city to itself and for any two cities there is at most one road between them. The country is connected, in the other words, it is possible to reach any city from any other city using the given roads.
The roads aren't all working. There are some roads which need some more work to be performed to be completely functioning.
The gang is going to rob a bank! The bank is located in city 1. As usual, the hardest part is to escape to their headquarters where the police can't get them. The gang's headquarters is in city n. To gain the gang's trust, Walter is in charge of this operation, so he came up with a smart plan.
First of all the path which they are going to use on their way back from city 1 to their headquarters n must be as short as possible, since it is important to finish operation as fast as possible.
Then, gang has to blow up all other roads in country that don't lay on this path, in order to prevent any police reinforcements. In case of non-working road, they don't have to blow up it as it is already malfunctional.
If the chosen path has some roads that doesn't work they'll have to repair those roads before the operation.
Walter discovered that there was a lot of paths that satisfied the condition of being shortest possible so he decided to choose among them a path that minimizes the total number of affected roads (both roads that have to be blown up and roads to be repaired).
Can you help Walter complete his task and gain the gang's trust?
Input
The first line of input contains two integers n, m (2 ≤ n ≤ 105, ), the number of cities and number of roads respectively.
In following m lines there are descriptions of roads. Each description consists of three integers x, y, z (1 ≤ x, y ≤ n, ) meaning that there is a road connecting cities number x and y. If z = 1, this road is working, otherwise it is not.
Output
In the first line output one integer k, the minimum possible number of roads affected by gang.
In the following k lines output three integers describing roads that should be affected. Each line should contain three integers x, y, z (1 ≤ x, y ≤ n, ), cities connected by a road and the new state of a road. z = 1 indicates that the road between cities x and y should be repaired and z = 0 means that road should be blown up.
You may output roads in any order. Each affected road should appear exactly once. You may output cities connected by a single road in any order. If you output a road, it's original state should be different from z.
After performing all operations accroding to your plan, there should remain working only roads lying on some certain shortest past between city 1 and n.
If there are multiple optimal answers output any.
Examples
input
2 1
1 2 0
output
1
1 2 1
input
4 4
1 2 1
1 3 0
2 3 1
3 4 1
output
3
1 2 0
1 3 1
2 3 0
input
8 9
1 2 0
8 3 0
2 3 1
1 4 1
8 7 0
1 5 1
4 6 1
5 7 0
6 8 0
output
3
2 3 0
1 5 0
6 8 1
Note
In the first test the only path is 1 - 2
In the second test the only shortest path is 1 - 3 - 4
In the third test there are multiple shortest paths but the optimal is 1 - 4 - 6 - 8
大概意思就是给定 n 个点, m 条边的有向图,边权都为 1,一些需要维修。
你需要选择1条 1 到 n 的最短路,将它们修好,并炸毁其它所
有不在路径上的完好的路。
若有多条最短路,选择影响值最小的。
影响值 = 维修的路数 + 炸毁的路数。
我大概想了一下,应该就是找一条最短路上的边权最大。。。
然后这个dp是按照dis转移的,必须是dis + 1才可以满足最短路。。。
但是好像可以分层图啥的。。。不会啊
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct lpl{
int to, dis;
}lin, from[maxn];
struct ld{
int a, b;
bool operator < (const ld &A)const{
if(a == A.a) return b < A.b;
return a < A.a;
}
}asd;
int n, m, r, sum, dis[maxn], f[maxn];
bool vis[maxn];
vector<int> edge[maxn];
vector<lpl> point[maxn];
queue<int> q;
set<ld> s;
inline void putit()
{
scanf("%d%d", &n, &m);
for(int a, b, i = 1; i <= m; ++i){
scanf("%d%d%d", &a, &b, &lin.dis); sum += lin.dis;
edge[a].push_back(b); edge[b].push_back(a);
lin.to = b; point[a].push_back(lin);
lin.to = a; point[b].push_back(lin);
}
}
inline void spfa()
{
int now, qwe; q.push(1); memset(dis, 0x3f, sizeof(dis)); dis[1] = 0;
while(!q.empty()){
now = q.front(); q.pop(); vis[now] = false;
for(int i = edge[now].size() - 1; i >= 0; --i){
qwe = edge[now][i];
if(dis[qwe] > dis[now] + 1){
dis[qwe] = dis[now] + 1;
if(!vis[qwe]){
vis[qwe] = true; q.push(qwe);
}
}
}
}
}
int dp(int t)
{
if(vis[t]) return f[t];
vis[t] = true;
for(int i = point[t].size() - 1; i >= 0; --i){
int now = point[t][i].to;
if(dis[t] != dis[now] + 1) continue;
if(f[t] <= dp(now) + point[t][i].dis){
f[t] = f[now] + point[t][i].dis;
from[t].to = now; from[t].dis = point[t][i].dis;
}
}
return f[t];
}
inline void workk()
{
printf("%d\n", sum + dis[n] - 2 * dp(n)); int t = n;
while(t != 1){
asd.a = t; asd.b = from[t].to;
if(asd.a > asd.b) swap(asd.a, asd.b); s.insert(asd); t = from[t].to;
}
for(int i = 1; i <= n; ++i){
for(int j = point[i].size() - 1; j >= 0; --j){
lin = point[i][j]; if(lin.to > i) continue;
asd.a = lin.to; asd.b = i;
if(s.count(asd)){
if(!lin.dis) printf("%d %d 1\n", asd.a, asd.b);
}
else{
if(lin.dis) printf("%d %d 0\n", asd.a, asd.b);
}
}
}
}
int main()
{
putit();
spfa();
workk();
return 0;
}
Codeforces Breaking Good的更多相关文章
- 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 507E] Breaking Good
[题目链接] https://codeforces.com/contest/507/problem/E [算法] 首先BFS求出1到其余点的最短路 , N到其余点的最短路,记为distA[]和dist ...
- CodeForces 507E Breaking Good 2维权重dij
Breaking Good 题解: 2维权重dij, 先距离最短, 后改变最小. 在这个题中, 如果要改变最小, 则让更多的可用边放进来. 然后可以用pre存下关键边. 代码: ...
- 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 ...
- 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 507E】Breaking Good
[题目链接]:https://vjudge.net/contest/164884#problem/D [题意] 给你一张图; 图中有些路是完好的;但有些路还没修好; 先不管路有没有修好; 问你从起点到 ...
- Codeforces Round #531 (Div. 3) C. Doors Breaking and Repairing (博弈)
题意:有\(n\)扇门,你每次可以攻击某个门,使其hp减少\(x\)(\(\le 0\)后就不可修复了),之后警察会修复某个门,使其hp增加\(y\),问你最多可以破坏多少扇门? 题解:首先如果\(x ...
- Codeforces Educational Codeforces Round 15 D. Road to Post Office
D. Road to Post Office time limit per test 1 second memory limit per test 256 megabytes input standa ...
随机推荐
- canvas 画正方形和圆形
绘制正方形 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- python类中方法__str__()和__repr__()简单粗暴总结
在交互式模式下,类中同时实现__str__()和__repr__()方法: 直接输入实例名称显示repr返回的类容: 用print打印实例名称显示str返回的内容: >>> clas ...
- CS184.1X 计算机图形学导论(第四讲)
一.齐次变换 1.平移变换 变换矩阵不能包含X,Y,Z等坐标变量 如果x坐标向右平移了5个单位长度,则x~=x+5.在变换矩阵中表示的时候添加一个w坐标变量.通过加入一个w坐标,可以实现平移变换 1& ...
- 【串线篇】spring boot配置文件大全【上】
一.配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的: • application.properties • application.yml 配置文件的作用:修改SpringB ...
- Jmeter --Json Extractor (后置处理器)
一.使用场景 Json Extractor 后置处理器用在返回格式为json的HTTP请求中, 用来获取返回的json中的某个值.并保存成变量供后面的请求进行调用或者断言等. 二.使用方法 1.创建H ...
- toj 4602 松鼠聚会
题目: 草原上住着一群小松鼠,每个小松鼠都有一个家.时间长了,大家觉得应该聚一聚.但是草原非常大,松鼠们都很头疼应该在谁家聚会才最合理. 每个小松鼠的家可以用一个点x,y表示,两个点的距离定义为:点( ...
- python使用qq邮箱向163邮箱发送邮件、附件
在生成html测试报告后 import smtplib,time from email.mime.text import MIMEText from email.mime.multipart impo ...
- 英语单词SYNOPSIS
SYNOPSIS 来源——man帮助内容 BASH() General Commands Manual BASH() NAME bash - GNU Bourne-Again SHell SYNOPS ...
- flask中间件请求流程
from flask import Flask,session,url_for,request,flash,get_flashed_messages app = Flask(__name__) app ...
- FMXUI ANDROID下连续按多次返回出现异常
在ANDROID下,按返回键后,默认是关闭当前Frame,但连接按返回键,会对当前Frame执行多次关闭动作,因为已经释放过对象,再次关闭会出现异常错误,解决办法:定义一个标识如FClosed: ...