Codeforces Round #287 (Div. 2) E. Breaking Good 最短路
题目链接:
http://codeforces.com/problemset/problem/507/E
E. Breaking Good
time limit per test2 secondsmemory limit per test256 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?
#### 输入
> 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.
#### 输出
> 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.
> ####样例输入
> 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
样例输出
3
2 3 0
1 5 0
6 8 1
题意
给你n个点,m条边的图,每条边长度都为1,如果标记为0,则这条边待修,1则可正常使用,现在让你找一条最短路,路径上面的待修理的边最少。
题解
跑完最短路之后建最短路构成的DAG图,然后跑拓扑排序跑dp。
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef __int64 LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=1e5+10;
struct Edge{
int u,v,z;
Edge(int u,int v,int z):u(u),v(v),z(z){}
};
struct Spfa{
int n,m;
vector<Edge> egs;
VI G[maxn],G2[maxn];
bool inq[maxn];
int d[maxn],d2[maxn];
void init(int n){
this->n=n;
for(int i=0;i<n;i++) G[i].clear();
egs.clear();
}
void addEdge(int u,int v,int z){
egs.pb(Edge(u,v,z));
m=egs.sz();
G[u].pb(m-1);
}
int spfa(int s,int *d){
queue<int> Q;
clr(inq,0);
rep(i,0,n) d[i]=INF;
d[s]=0,inq[s]=true,Q.push(s);
while(!Q.empty()){
int u=Q.front(); Q.pop();
inq[u]=false;
for(int i=0;i<G[u].sz();i++){
Edge& e=egs[G[u][i]];
if(d[e.v]>d[u]+1){
d[e.v]=d[u]+1;
if(!inq[e.v]){
Q.push(e.v);
inq[e.v]=true;
}
}
}
}
}
int ind[maxn],dp[maxn];
int pre[maxn];
bool vis[maxn*2];
void solve(){
clr(pre,-1);
clr(ind,0);
clr(vis,0);
clr(dp,0x3f);
spfa(0,d);
spfa(n-1,d2);
for(int i=0;i<m;i++){
Edge &e=egs[i];
if(d[e.u]+1+d2[e.v]==d[n-1]){
// prf("(%d,%d)\n",e.u+1,e.v+1);
G2[e.u].pb(i);
ind[e.v]++;
}
}
//
queue<int> Q;
Q.push(0),dp[0]=0;
while(!Q.empty()){
int u=Q.front(); Q.pop();
rep(i,0,G2[u].sz()){
Edge& e=egs[G2[u][i]];
if(dp[e.v]>dp[u]+(e.z^1)){
dp[e.v]=dp[u]+(e.z^1);
pre[e.v]=G2[u][i];
}
ind[e.v]--;
if(ind[e.v]==0){
Q.push(e.v);
}
}
}
// bug(dp[n-1]);
VI ans;
int p=n-1;
while(p){
Edge& e=egs[pre[p]];
// prf("<%d,%d>\n",e.u,e.v);
if(e.z==0){
ans.pb(pre[p]);
}
vis[pre[p]]=vis[pre[p]^1]=1;
p=e.u;
}
for(int i=0;i<m;i++){
if(vis[i]) continue;
Edge& e=egs[i];
if(e.z==1){
ans.pb(i);
}
vis[i]=vis[i^1]=1;
}
prf("%d\n",ans.sz());
rep(i,0,ans.sz()){
Edge& e=egs[ans[i]];
prf("%d %d %d\n",e.u+1,e.v+1,e.z^1);
}
}
}spfa;
int main() {
int n,m;
scf("%d%d",&n,&m);
spfa.init(n);
for(int i=0;i<m;i++){
int u,v,z;
scf("%d%d%d",&u,&v,&z); u--,v--;
spfa.addEdge(u,v,z);
spfa.addEdge(v,u,z);
}
spfa.solve();
return 0;
}
//end-----------------------------------------------------------------------
其实。。spfa跑最短路的时候就能处理出0最少的最短路径了。。orz..上面的做法好蠢。。
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef __int64 LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=1e5+10;
struct Edge{
int u,v,z;
Edge(int u,int v,int z):u(u),v(v),z(z){}
};
struct Spfa{
int n,m;
vector<Edge> egs;
VI G[maxn];
bool inq[maxn];
int d[maxn],dp[maxn];
int pre[maxn];
void init(int n){
this->n=n;
for(int i=0;i<n;i++) G[i].clear();
egs.clear();
}
void addEdge(int u,int v,int z){
egs.pb(Edge(u,v,z));
m=egs.sz();
G[u].pb(m-1);
}
int spfa(int s){
clr(pre,-1);
clr(dp,0x3f);
queue<int> Q;
clr(inq,0);
rep(i,0,n) d[i]=INF;
dp[s]=0;
d[s]=0,inq[s]=true,Q.push(s);
while(!Q.empty()){
int u=Q.front(); Q.pop();
inq[u]=false;
for(int i=0;i<G[u].sz();i++){
Edge& e=egs[G[u][i]];
if(d[e.v]>d[u]+1||d[e.v]==d[u]+1&&dp[e.v]>dp[u]+(e.z^1)){
d[e.v]=d[u]+1;
dp[e.v]=dp[u]+(e.z^1);
pre[e.v]=G[u][i];
if(!inq[e.v]){
Q.push(e.v);
inq[e.v]=true;
}
}
}
}
}
bool vis[maxn*2];
void solve(){
clr(vis,0);
spfa(0);
VI ans;
int p=n-1;
while(p){
Edge& e=egs[pre[p]];
if(e.z==0){
ans.pb(pre[p]);
}
vis[pre[p]]=vis[pre[p]^1]=1;
p=e.u;
}
for(int i=0;i<m;i++){
if(vis[i]) continue;
Edge& e=egs[i];
if(e.z==1){
ans.pb(i);
}
vis[i]=vis[i^1]=1;
}
prf("%d\n",ans.sz());
rep(i,0,ans.sz()){
Edge& e=egs[ans[i]];
prf("%d %d %d\n",e.u+1,e.v+1,e.z^1);
}
}
}spfa;
int main() {
int n,m;
scf("%d%d",&n,&m);
spfa.init(n);
for(int i=0;i<m;i++){
int u,v,z;
scf("%d%d%d",&u,&v,&z); u--,v--;
spfa.addEdge(u,v,z);
spfa.addEdge(v,u,z);
}
spfa.solve();
return 0;
}
//end-----------------------------------------------------------------------
代码
Codeforces Round #287 (Div. 2) E. Breaking Good 最短路的更多相关文章
- 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 Round #287 (Div. 2) A. Amr and Music
题目传送门 /* 贪心水题 */ #include <cstdio> #include <algorithm> #include <iostream> #inclu ...
- Codeforces Round #287 (Div. 2) C. Guess Your Way Out! 思路
C. Guess Your Way Out! time limit per test 1 second memory limit per test 256 megabytes input standa ...
- CodeForces Round #287 Div.2
A. Amr and Music (贪心) 水题,没能秒切,略尴尬. #include <cstdio> #include <algorithm> using namespac ...
- Codeforces Round #287 (Div. 2) C. Guess Your Way Out! 水题
C. Guess Your Way Out! time limit per test 1 second memory limit per test 256 megabytes input standa ...
- Codeforces Round #287 (Div. 2) B. Amr and Pins 水题
B. Amr and Pins time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
- Codeforces Round #287 (Div. 2) A. Amr and Music 水题
A. Amr and Music time limit per test 1 second memory limit per test 256 megabytes input standard inp ...
- Codeforces Round #287 (Div. 2) D. The Maths Lecture [数位dp]
传送门 D. The Maths Lecture time limit per test 1 second memory limit per test 256 megabytes input stan ...
随机推荐
- string函数库的原型
#ifndef __HAVE_ARCH_STRCPY /** * strcpy - Copy a %NUL terminated string * @dest: Where to copy the s ...
- Bessel函数的零点计算 MATLAB
由于MATLAB自己没有附带贝塞尔函数零点,因此使用起来很不方便,特别是在绘制仿真场量时. 下面给出0-9阶的贝塞尔函数零点的计算公式,其中理论上计算零点个数N在50以内时较为精确: function ...
- 《Java程序设计》实验三(敏捷开发与XP实践)20155214 实验报告
<JAVA程序设计> 实验三(敏捷开发与XP实践) 实验内容 XP基础 XP核心实践 相关工具 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>< ...
- od源代码
```/* od -- dump files in octal and other formats Copyright (C) 92, 1995-2002 Free Software Foundati ...
- 可能是全网首个支持阿里云Elasticsearch Xapck鉴权的Skywalking
可能是全网首个支持阿里云Elasticsearch Xapck鉴权的Skywalking 对Skywalking有兴趣的同学参见:年轻人的第一个APM-Skywalking 之前在搭建Skywalki ...
- [FJOI2016]建筑师 斯特林数
早期作品,不喜轻喷. LG传送门 组合数与斯特林数的基本应用. 组合数 大家应该都熟悉它的表达式,但我们这里使用它的递推式会更加方便,下面推导组合数的递推式.设\(\binom{n}{m}\)表示在\ ...
- 修改索引名称(mysql)
MySQL修改索引名称. 对于MySQL 5.7及以上版本,可以执行以下命令: ALTER TABLE tbl_name RENAME INDEX old_index_name TO new_inde ...
- iOS上架被拒理由及相关解决方案记录
注:苹果客服中国区电话:4006 701 855 最近公司上线一个电动车工具类项目,被拒无数次,今天上架了,记录一下 01 苹果拒绝理由(内购和后台定位) We noticed that your a ...
- 深入解析QML引擎, 第2部分: 绑定(Bindings)
原文 QML Engine Internals, Part 2: Bindings 译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/QML爱好 ...
- 422. Length of Last Word【LintCode java】
Description Given a string s consists of upper/lower-case alphabets and empty space characters ' ', ...