1. 程式人生 > >luogu P1186 瑪麗卡

luogu P1186 瑪麗卡

道路 ron 女朋友 ont set 城市 國家 opera std

題目描述

麥克找了個新女朋友,瑪麗卡對他非常惱火並伺機報復。

因為她和他們不住在同一個城市,因此她開始準備她的長途旅行。

在這個國家中每兩個城市之間最多只有一條路相通,並且我們知道從一個城市到另一個城市路上所需花費的時間。

麥克在車中無意中聽到有一條路正在維修,並且那兒正堵車,但沒聽清楚到底是哪一條路。無論哪一條路正在維修,從瑪麗卡所在的城市都能到達麥克所在的城市。

瑪麗卡將只從不堵車的路上通過,並且她將按最短路線行車。麥克希望知道在最糟糕的情況下瑪麗卡到達他所在的城市需要多長時間,這樣他就能保證他的女朋友離開該城市足夠遠。

編寫程序,幫助麥克找出瑪麗卡按最短路線通過不堵車道路到達他所在城市所需的最長時間(用分鐘表示)。

輸入輸出格式

輸入格式:

第一行有兩個用空格隔開的數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
heap優化Dijkstra先求出無障礙最短路,
再枚舉當最短路上某一段障礙時情況
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define INF 0x3f3f3f3f
#define
N 1020 int n,m; int head[N]; int dis[N]; struct nnode{ int v;int w,next; }edge[N*N/2]; struct node{ int v,dis; friend bool operator < (node a,node b){ return a.dis>b.dis; } }cur; priority_queue<node>q; int read() { int x=0,f=1; char c; while (c<0 || c>9) {if(c==-)f = -1;c = getchar();} while (c>=0 && c<=9)x=x*10+c-0,c=getchar(); return x*f; } int num = 0; void add_edge(int x,int y,int w) { edge[num].v=y; edge[num].w=w; edge[num].next=head[x]; head[x]=num++; } int pre_now[N]; int pre[N]; int Dijkstra(int p,int tp) { //memset (head,-1,sizeof -1); memset (dis,0x3f,sizeof dis); dis[1] = 0; q.push(node{1,0}); while(!q.empty()) { cur = q.top(); q.pop(); if(dis[cur.v]<cur.dis)continue; int u = cur.v; for (int i = head[u];i != -1;i = edge[i].next) { int v = edge[i].v; if((v == p && u== tp) || (v==tp && p == u))continue; if(dis[v]>dis[u]+edge[i].w) { dis[v]=dis[u]+edge[i].w; pre_now[v]=u; q.push((node){v,dis[v]}); } } } return dis[n]; } int main() { n = read(); m = read(); for(int i=1;i<=n;i++)head[i]=-1; for (int i = 1; i <= m; i++){ int a,b,c; a = read(),b = read(),c = read(); add_edge(a,b,c);add_edge(b,a,c); } int ans=Dijkstra(0,0); memcpy(pre,pre_now,sizeof(pre)); int k=n; while(k) { int tmp = Dijkstra(pre[k],k); if(tmp!=INF) ans = max(ans,tmp); k = pre[k]; } printf("%d\n",ans); return 0; }

luogu P1186 瑪麗卡