您的位置:首页 > 其它

[codevs]1021 玛丽卡

2016-04-27 18:16 316 查看
1021 玛丽卡

时间限制: 2 s

空间限制: 128000 KB

题目等级 : 大师 Master

题解

题目描述 Description

麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。

因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。

在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。

麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。

玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。

编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。

输入描述 Input Description

第一行有两个用空格隔开的数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分钟内是就能通过。

输出描述 Output Description

输出文件的第一行中写出用分钟表示的最长时间,在这段时间中,无论哪条路在堵车,玛丽卡应该能够到达麦克处,如果少于这个时间的话,则必定存在一条路,该条路一旦堵车,玛丽卡就不能够赶到麦克处。

样例输入 Sample Input

5 7

1 2 8

1 4 10

2 3 9

2 4 10

2 5 1

3 4 7

3 5 10

样例输出 Sample Output

27

首先要明白这题是最短路(众人:废话!)

其实 你要删的边肯定都在一开始没删的时候的最短路上

╮(╯_╰)╭不然怎么跑

跑完一遍最短路后,记录,删边,再跑

删边==不跑这条边

嗯嗯 两遍spfa代码如下

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN = 1000000 + 5;
int n,m,f,t,v,c,tot = 0,ans = 0;
int first[MAXN],next[MAXN << 1],dis[MAXN],pre[MAXN];
bool use[MAXN];
struct edge
{
int f,t,v;
}l[MAXN << 1];

void build(int f,int t,int v)
{
l[tot] = (edge){f,t,v};
next[tot] = first[f];
first[f] = tot;
tot ++;
return;
}

void spfa(int s)
{
deque<int>q;
memset(use,0,sizeof(use));
memset(dis,0x3f,sizeof(dis));
while(!q.empty())
q.pop_front();
q.push_back(0);
q.push_back(s);
use[s] = true;
dis[s] = 0;
while(!q.empty())
{
int u = q.front();
q.pop_front();
use[u] = false;
for(int i = first[u]; i != -1; i = next[i])
{
int w = l[i].t;
if(dis[w] > dis[u] + l[i].v)
{
dis[w] = dis[u] + l[i].v;
pre[w] = i;//记录最短路经过哪些点
if(!use[w])
{
use[w] = true;
if(dis[w] < dis[q.front()])
q.push_front(w);
else
q.push_back(w);
}
}
}
}
return;
}

void spfa2(int s,int r)
{
queue <int> q;
memset(use,0,sizeof(use));
memset(dis,0x3f,sizeof(dis));
while(!q.empty())
q.pop();
q.push(s);
use[s] = true;
dis[s] = 0;
while(!q.empty())
{
int u = q.front();
q.pop();
use[u] = false;
for(int i = first[u]; i != -1; i = next[i])
{
//就是这个地方QAQ 判断是否跑这条边
if(i == r || i == (r ^ 1))
{
continue;
}
int w = l[i].t;
if(dis[w] > dis[u] + l[i].v)
{
dis[w] = dis[u] + l[i].v;
q.push(w);
use[w] = true;
}
}
}
return;
}

int main()
{
memset(first,0xff,sizeof(first));
memset(pre,0xff,sizeof(pre));
scanf("%d %d",&n,&m);
for(int i = 1; i <= m; i ++)
{
scanf("%d %d %d",&f,&t,&v);
build(f,t,v);
build(t,f,v);
}
spfa(1);
ans = max(ans,dis
);//跑完一遍后,记录
int x = n;
while(x)//跑之后的最短路╮(╯_╰)╭
{
spfa2(1,pre[x]);
ans = max(ans,dis
);
x = l[pre[x]].f;
}
//然后就是输出了23333
printf("%d",ans);
return 0;
}


(:зゝ∠) 蒟蒻只求不打脸

QAQ orz you all
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: