1. 程式人生 > >[SDOI2009]Elaxia的路線

[SDOI2009]Elaxia的路線

題目描述

最近,Elaxia和w**的關係特別好,他們很想整天在一起,但是大學的學習太緊張了,他們 必須合理地安排兩個人在一起的時間。

Elaxia和w**每天都要奔波於宿舍和實驗室之間,他們 希望在節約時間的前提下,一起走的時間儘可能的長。

現在已知的是Elaxia和w**所在的宿舍和實驗室的編號以及學校的地圖:地圖上有N個路 口,M條路,經過每條路都需要一定的時間。 具體地說,就是要求無向圖中,兩對點間最短路的最長公共路徑。 輸入輸出格式 輸入格式:

第一行:兩個整數N和M(含義如題目描述)。

第二行:四個整數x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ y2 ≤ N),分別表示Elaxia的宿舍和實驗室及w**的宿舍和實驗室的標號(兩對點分別 x1,y1和x2,y2)。

接下來M行:每行三個整數,u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之間有一條路,經過這條路所需要的時間為l。

輸出格式:

一行,一個整數,表示每天兩人在一起的時間(即最長公共路徑的長度)

輸入輸出樣例 輸入樣例#1: 複製

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

輸出樣例#1: 複製

3

說明

對於30%的資料,N ≤ 100;

對於60%的資料,N ≤ 1000;

對於100%的資料,N ≤ 1500,輸入資料保證沒有重邊和自環。

題意: 給定兩對點,求其最短路間的最長公共路徑,

思路: 怎麼確定一條邊在最短路上,這個問題很容易解決; 那麼我們先跑4遍spfa,然後將其最短路上面的公共邊建一個新圖; 求其最長鏈即可;

#include<bits/stdc++.h>
using namespace std;
#define maxn 2000005
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define inf 0x3f3f3f3f
int n,m;
int head[maxn],Head[maxn],degree[maxn];
int tot,Tot;
int dis[
maxn]; int s1[maxn],s2[maxn],t1[maxn],t2[maxn]; int vis[maxn]; queue<int>q; struct node{ int u,v,w; int nxt; }e[maxn],E[maxn]; void addedge(int u,int v,int w){ e[++tot].v=v;e[tot].u=u;e[tot].w=w; e[tot].nxt=head[u];head[u]=tot; } void add(int u,int v,int w){ E[++Tot].v=v;E[Tot].w=w;E[Tot].nxt=Head[u]; Head[u]=Tot;degree[v]++; } void spfa(int s,int d[]){ for(int i=0;i<=n;i++)d[i]=inf,vis[i]=0; d[s]=0;vis[s]=1; q.push(s); while(!q.empty()){ int u=q.front();q.pop(); vis[u]=0; for(int i=head[u];i;i=e[i].nxt){ int v=e[i].v; if(d[v]>d[u]+e[i].w){ d[v]=d[u]+e[i].w; if(!vis[v]){ q.push(v);vis[v]=1; } } } } } void topsort(){ for(int i=1;i<=n;i++){ dis[i]=0; if(!degree[i]){ q.push(i); } } int res=0; while(!q.empty()){ int u=q.front();q.pop(); for(int i=Head[u];i;i=E[i].nxt){ int v=E[i].v; dis[v]=max(dis[v],dis[u]+E[i].w); res=max(res,dis[v]);degree[v]--; if(!degree[v]){ q.push(v); } } } cout<<res<<endl; } int main(){ rdint(n);rdint(m); int xx1,xx2,yy1,yy2; rdint(xx1);rdint(yy1);rdint(xx2);rdint(yy2); for(int i=1;i<=m;i++){ int u,v,w;rdint(u);rdint(v);rdint(w); addedge(u,v,w);addedge(v,u,w); } spfa(xx1,s1);spfa(yy1,t1);spfa(xx2,s2);spfa(yy2,t2); for(int i=1;i<=tot;i+=2){ int u=e[i].u,v=e[i].v,w=e[i].w; int k1=min(s1[u],s1[v])+min(t1[u],t1[v])+w; int k2=min(s2[u],s2[v])+min(t2[u],t2[v])+w; if(k1==s1[yy1]&&k2==s2[yy2]){ if(s1[u]<s1[v])add(u,v,w); else add(v,u,w); } } topsort(); }