[SDOI2009]Elaxia的路線
阿新 • • 發佈:2018-12-11
題目描述
最近,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();
}