您的位置:首页 > 其它

hdu1595 find the longest of the shortest(dijkstra+枚举)

2016-11-17 20:36 309 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1595

题意:玛丽卡很生气因为她知道她男友米尔科交到了新的女朋友,于是要去找他算账。但是他们不在一个城市,玛丽卡在N,米尔科在1。米尔科无意中听到有一条路在修路,但是不知道是哪一条。他想让他的新女友去别的地方躲一躲,已知玛丽卡走的肯定是最短路,但是遇到修的路就会走别的路。求问玛丽卡最迟会花费多少时间赶来,好让他新女友在这段时间内去别的地方。(这题意真是醉了= =)

思路:求所有在可以删一条任意边前提下的最短路的最大值。这条边是任意的,但是边数是1000*1000,直接枚举肯定不行。可以发现,在所有路中,最短路之外的边删去并不影响最短路,也就是说删去最短路中的边最短路的值才会增大。知道了这一点这题就秒杀了。不过用spfa会超时,于是这题就给了这样的道理:

一旦有负权用spfa,spfa超时用dijkstra。

#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;

const int N = 1005;
const int INF = 0x3f3f3f3f;

int dis
, G

, pre
, ans
, pre0
, n;
bool vis
;

void dijkstra(int s)
{
memset(vis, false, sizeof(vis));
memset(pre, -1, sizeof(pre));
for(int i = 1; i <= n; i++)
dis[i] = INF;
dis[s] = 0;
for(int i = 1; i <= n; i++)
{
int k = -1;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && (k==-1 || dis[j]<dis[k]))
k = j;
}
if(k == -1) break;//已经遍历所有的点
vis[k] = true;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && dis[k]+G[k][j]<dis[j])
{
dis[j] = dis[k]+G[k][j];
pre[j] = k;
}
}
}
}

int main()
{
// freopen("in.txt", "r", stdin);
int m, s, e, w;
while(~scanf("%d%d", &n, &m))
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(i == j) G[i][j] = 0;
else G[i][j] = INF;
}
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &s, &e, &w);
G[s][e] = G[e][s] = w;
}
dijkstra(n);
memcpy(pre0, pre, sizeof(pre0));
int now = 1, ans = -INF;
int city, tmp;
while(now != -1)
{
city = pre0[now];
tmp = G[now][city];
G[now][city] = G[city][now] = INF;
dijkstra(n);
ans = max(ans, dis[1]);
G[now][city] = G[city][now] = tmp;//还原
now = pre0[now];
}
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu