507E Breaking Good (最短路+记录路径)
2015-01-30 21:20
246 查看
E. Breaking Good
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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 yshould 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.
Sample test(s)
input
output
input
output
input
output
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条边,每条边有编号z=1边是好的,z=0边是坏的,问从点1出发到点n的最短路,当最短路有多条时取修正值小的结果。修正的值=多余的好路(边)+要用的坏路(边),输入输出有格式。
分析:最短路+记录前驱
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int MAXN=100100;
const int INF=0x3f3f3f3f;
struct Edge
{
int u,v,id;
int cost;
Edge(int _u=0,int _v=0,int _cost=0,int _id=0):u(_u),v(_v),cost(_cost),id(_id) {}
};
vector<Edge>E[MAXN];
int x[MAXN],y[MAXN],z[MAXN];
void addedge(int u,int v,int w,int id)
{
E[u].push_back(Edge(u,v,w,id));
}
bool vis[MAXN];//在队列标志
int dist[MAXN],s[MAXN],pre[MAXN][2];
void SPFA(int start,int n)
{
memset(vis,false,sizeof(vis));
memset(s,-1,sizeof(s));
for(int i=1; i<=n; i++)dist[i]=INF;
dist[start]=0;
s[start]=0;
queue<int>que;
while(!que.empty())que.pop();
que.push(start);
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=false;
for(int i=0; i<E[u].size(); i++)
{
int v=E[u][i].v;
if(dist[v]>dist[u]+1||(dist[v]==dist[u]+1&&s[v]<s[u]+E[u][i].cost))
{
dist[v]=dist[u]+1;
s[v]=s[u]+E[u][i].cost;
pre[v][0]=u;//记录前驱结点u
pre[v][1]=i;//记录u->v边所对应u集合里的序号
if(!vis[v])
{
vis[v]=true;
que.push(v);
}
}
}
}
}
int main()
{
int ok[MAXN],n,m,cntt=0;
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&x[i],&y[i],&z[i]);
if(z[i])
cntt++;
addedge(x[i],y[i],z[i],i);
addedge(y[i],x[i],z[i],i);
}
SPFA(1,n);
memset(ok,0,sizeof(ok));
printf("%d\n",cntt-s
*2+dist
);
// for(int i=1; i<=m; i++) printf("pre[%d][0]=%d,pre[%d][1]=%d\n",i,pre[i][0],i,pre[i][1]);
int t=n;
while(t!=1)
{
// printf("t=%d\n",t);
if(E[pre[t][0]][pre[t][1]].cost==0)
ok[E[pre[t][0]][pre[t][1]].id]=1;
else
ok[E[pre[t][0]][pre[t][1]].id]=-1;
t=E[pre[t][0]][pre[t][1]].u;
}
for (int i = 1; i <= m; i++)
{
if (ok[i] == 1 || ok[i] == 0 && z[i])
printf ("%d %d %d\n", x[i], y[i], !z[i]);
}
}
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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 yshould 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.
Sample test(s)
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条边,每条边有编号z=1边是好的,z=0边是坏的,问从点1出发到点n的最短路,当最短路有多条时取修正值小的结果。修正的值=多余的好路(边)+要用的坏路(边),输入输出有格式。
分析:最短路+记录前驱
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int MAXN=100100;
const int INF=0x3f3f3f3f;
struct Edge
{
int u,v,id;
int cost;
Edge(int _u=0,int _v=0,int _cost=0,int _id=0):u(_u),v(_v),cost(_cost),id(_id) {}
};
vector<Edge>E[MAXN];
int x[MAXN],y[MAXN],z[MAXN];
void addedge(int u,int v,int w,int id)
{
E[u].push_back(Edge(u,v,w,id));
}
bool vis[MAXN];//在队列标志
int dist[MAXN],s[MAXN],pre[MAXN][2];
void SPFA(int start,int n)
{
memset(vis,false,sizeof(vis));
memset(s,-1,sizeof(s));
for(int i=1; i<=n; i++)dist[i]=INF;
dist[start]=0;
s[start]=0;
queue<int>que;
while(!que.empty())que.pop();
que.push(start);
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=false;
for(int i=0; i<E[u].size(); i++)
{
int v=E[u][i].v;
if(dist[v]>dist[u]+1||(dist[v]==dist[u]+1&&s[v]<s[u]+E[u][i].cost))
{
dist[v]=dist[u]+1;
s[v]=s[u]+E[u][i].cost;
pre[v][0]=u;//记录前驱结点u
pre[v][1]=i;//记录u->v边所对应u集合里的序号
if(!vis[v])
{
vis[v]=true;
que.push(v);
}
}
}
}
}
int main()
{
int ok[MAXN],n,m,cntt=0;
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&x[i],&y[i],&z[i]);
if(z[i])
cntt++;
addedge(x[i],y[i],z[i],i);
addedge(y[i],x[i],z[i],i);
}
SPFA(1,n);
memset(ok,0,sizeof(ok));
printf("%d\n",cntt-s
*2+dist
);
// for(int i=1; i<=m; i++) printf("pre[%d][0]=%d,pre[%d][1]=%d\n",i,pre[i][0],i,pre[i][1]);
int t=n;
while(t!=1)
{
// printf("t=%d\n",t);
if(E[pre[t][0]][pre[t][1]].cost==0)
ok[E[pre[t][0]][pre[t][1]].id]=1;
else
ok[E[pre[t][0]][pre[t][1]].id]=-1;
t=E[pre[t][0]][pre[t][1]].u;
}
for (int i = 1; i <= m; i++)
{
if (ok[i] == 1 || ok[i] == 0 && z[i])
printf ("%d %d %d\n", x[i], y[i], !z[i]);
}
}
相关文章推荐
- 最短路记录路径——PKU 2457
- PAT天梯赛L2-001. 紧急救援 dijk经典最短路劲+点权最大+记录路径
- 最短路 记录路径
- POJ2457 Part Acquisition(Spfa最短路+记录路径)
- HDOJ 题目1595 find the longest of the shortest(枚举,最短路记录路径)
- HDU 1385 Minimum Transport Cost【最短路之路径记录】
- HDOJ 5294 Tricks Device 最短路(记录路径)+最小割
- HDU6181 Two Paths(次短路,路径记录,spfa,2017 HDU多校联赛 第10场)
- POJ 2457 Part Acquisition(记录路径单源最短路)
- pku2253 记录从初始到终点最小的路径(某一部分),迪杰斯特拉求最短路
- PAT L2-001. 紧急救援 (最短路变形 Dijkstra + 记录路径)
- 图论---最短路(记录路径)
- 城市间紧急救援 ,复杂点的最短路,记录路径,记录最短路个数等
- 最短路之 路径记录 dijkstra + floyd + SPFA 【小笔记】
- Nuc - 00005:兔子与樱花 (Floyd求最短路+路径记录)
- hdu 4871 树的分治+最短路记录路径
- Codeforces 507E Breaking Good【最短路SPFA+Dp+记录路径】好题~~~
- HDU 1385【两点间最短路, DIJK + 记录路径】
- hdu 4871 树的分治+最短路记录路径
- HDU ACM 3986 Harry Potter and the Final Battle(邻接表实现最短路dijkstra堆优化记录路径 + 枚举最短路上每条边)