洛谷 P1186 玛丽卡
题目
题目描述
麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。
因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。
在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。
麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。
玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。
编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。
输入输出格式
输入格式:
第一行有两个用空格隔开的数N和M,分别表示城市的数量以及城市间道路的数量。1≤N≤1000,1≤M≤N*(N-1)/2。城市用数字1至N标识,麦克在城市1中,玛丽卡在城市N中。
接下来的M行中每行包含三个用空格隔开的数A,B和V。其中1≤A,B≤N,1≤V≤1000。这些数字表示在A和城市B中间有一条双行道,并且在V分钟内是就能通过。
输出格式:
输出文件的第一行中写出用分钟表示的最长时间,在这段时间中,无论哪条路在堵车,玛丽卡应该能够到达麦克处,如果少于这个时间的话,则必定存在一条路,该条路一旦堵车,玛丽卡就不能够赶到麦克处。
输入输出样例
输入样例#1:
5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10
输出样例#1:
27
题解
首先,用spfa刷最短路,并记录每一条边,然后枚举哪一条边在施工,再刷spfa求出最大的时间既为答案(因为只有修改当前最短路里的边才能改变当前的最短路)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,tot;
int lnk[1005],d[1005],q[1005],pre[1005];
bool vis[1005];
struct edge
{
int x,y,v,nxt;
} e[1000005];
int readln()
{
int x=0;
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9') x=x*10+ch-48,ch=getchar();
return x;
}
int add(int x,int y,int v)
{
tot++;
e[tot].nxt=lnk[x];
lnk[x]=tot;
e[tot].y=y;
e[tot].v=v;
e[tot].x=x;
}
void spfa1()
{
memset(vis,0,sizeof(vis));
memset(q,0,sizeof(q));
for (int i=1;i<=n;i++) d[i]=1e9;
int head=0,tail=1;
q[1]=1;vis[1]=true;d[1]=0;
while (head!=tail)
{
head=head%n+1;
int x=q[head];
vis[x]=false;
for (int i=lnk[x];i;i=e[i].nxt)
{
if (d[x]+e[i].v<d[e[i].y])
{
d[e[i].y]=d[x]+e[i].v;
pre[e[i].y]=i;
if (!vis[e[i].y])
{
tail=tail%n+1;
q[tail]=e[i].y;
vis[q[tail]]=true;
}
}
}
}
}
void spfa2()
{
memset(vis,0,sizeof(vis));
memset(q,0,sizeof(q));
for (int i=1;i<=n;i++) d[i]=1e9;
int head=0,tail=1;
q[1]=1;vis[1]=true;d[1]=0;
while (head!=tail)
{
head=head%n+1;
int x=q[head];
vis[x]=false;
for (int i=lnk[x];i;i=e[i].nxt)
{
if (d[x]+e[i].v<d[e[i].y])
{
d[e[i].y]=d[x]+e[i].v;
if (!vis[e[i].y])
{
tail=tail%n+1;
q[tail]=e[i].y;
vis[q[tail]]=true;
}
}
}
}
}
int main()
{
int x,y,v,t;
n=readln();m=readln();
for (int i=1;i<=m;i++)
{
x=readln();y=readln();v=readln();
add(x,y,v);add(y,x,v);
}
spfa1();
int ans=d[n];
for (int i=pre[n];i;i=pre[e[i].x])
{
t=e[i].v;
e[i].v=1e9;
spfa2();
e[i].v=t;
ans=max(ans,d[n]);
}
printf("%d",ans);
return 0;
}