洛谷1186 玛丽卡

题目描述

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

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

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

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

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

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

输入格式

第一行有两个用空格隔开的数(N)(M),分别表示城市的数量以及城市间道路的数量。(1≤N≤1000),(1≤M≤N) ( imes) ((N-1))(/2)。城市用数字(1~N)标识,麦克在城市(1)中,玛丽卡在城市(N)中。

接下来的(M)行中每行包含三个用空格隔开的数(A,B,V)。其中(1≤A),(B≤N),(1≤V≤10001≤A,B≤N),(1≤V≤1000)。这些数字表示在(A)和城市(B)中间有一条双行道,并且在(V)分钟内是就能通过。

输出格式

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

样例

输入

5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10

输出

27

思路

先跑一遍最短路,将最短路的路径记录下来,

然后枚举每一条最短路的边,将其断掉,记录此时的1-n的时间

取其中最大的一个时间即为所求

代码

/************************************************
*Author        :  xzj213
*Created Time  :  2019.10.30.15:19
*Mail          :  xzj213@qq.com
*Problem       :  P1186
************************************************/
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000+5;
int beg[maxn*maxn],dis[maxn],n,m,vis[maxn],cut[maxn][maxn],fa[maxn],tot,ans;
bool flag;
struct edge{
	int nex,to,w;
}e[maxn*maxn];
void add(int x,int y,int z){
	e[++tot]=(edge){beg[x],y,z};
	beg[x]=tot;
}
int read() {
    int x=0,f=1;
    char ch=getchar();
    while(ch>57 || ch<48){if(ch==45)f=-1;ch=getchar();}
    while(ch<=57 && ch>=48){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
void Dijkstra(){
	priority_queue< pair<int,int> >q;
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[1]=0;
	q.push(make_pair(0,1));
	while(!q.empty()){
		int x=q.top().second;
		q.pop();
		if(vis[x])continue;
		vis[x]=1;
		for(int i=beg[x];i;i=e[i].nex){
			int y=e[i].to;
			if(!cut[y][x] && dis[y]>dis[x]+e[i].w){
				if(!flag)fa[y]=x;
				dis[y]=dis[x]+e[i].w;
				q.push(make_pair(-dis[y],y));
			}
		}
	}
}
int main() {
    n=read();m=read();
	for(int i=1,x,y,w;i<=m;i++){
		x=read();y=read();w=read();
		add(x,y,w);
		add(y,x,w);
	}
	Dijkstra();
	flag=1;
	for(int i=n;i!=1;i=fa[i]){
		cut[fa[i]][i]=1;
		cut[i][fa[i]]=1;
		Dijkstra();
		cut[fa[i]][i]=0;
		cut[i][fa[i]]=0;
		ans=max(ans,dis[n]);
	}
	cout<<ans<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/xzj213/p/11772230.html