bzoj1880

题意很清楚 我们只需预处理出同时在他们最短路上的边然后再在上面跑最长路即可 然而要考虑双向边的影响

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<ctime>
  5 #include<cmath>
  6 #include<iostream>
  7 #include<algorithm>
  8 #include<queue>
  9 #include<stack>
 10 #include<set>
 11 #define clr(a,x) memset(a,x,sizeof(a))
 12 #define rep(i,l,r) for(int i=(l);i<(r);i++)
 13 using namespace std;
 14 typedef long long ll;
 15 typedef pair<int,int> pii;
 16 #define mkp(a,b) make_pair(a,b)
 17 int read(){
 18     int ans=0,f=1;
 19     char c=getchar();
 20     while(!isdigit(c)){
 21         if(c=='-') f=-1;
 22         c=getchar();
 23     }
 24     while(isdigit(c)){
 25         ans=ans*10+c-'0';
 26         c=getchar();
 27     }
 28     return ans*f;
 29 }
 30 const int maxn=1509,maxm=1000009,inf=0x3fffffff;
 31 struct edge{
 32     int v,l,f;
 33     edge*next;
 34 }e[maxm],*fir[maxn],*pt=e;
 35 void addedge(int u,int v,int l){
 36     pt->v=v;pt->l=l;
 37     if(fir[u]) pt->next=fir[u];
 38     fir[u]=pt++;
 39 }
 40 void add(int u,int v,int l){
 41     addedge(u,v,l);addedge(v,u,l);
 42 }
 43 int ans,n,m,u1,v1,u2,v2,d[maxn],w[maxn];
 44 bool p[maxn],vis[maxn];
 45 void dijkstra(int S){
 46     priority_queue<pii,vector<pii>,greater<pii> >Q;
 47     rep(i,1,n+1) d[i]=inf;Q.push(mkp(d[S]=0,S));
 48     while(!Q.empty()){
 49         int dis=Q.top().first,x=Q.top().second;Q.pop();
 50         if(dis!=d[x]) continue;
 51         for(edge*e=fir[x];e;e=e->next){
 52             if(d[e->v]>dis+e->l){
 53                 d[e->v]=dis+e->l;
 54                 Q.push(mkp(d[e->v],e->v));
 55             }
 56         }
 57     }
 58 }
 59 void dfs(int x){
 60     if(vis[x]) return;
 61     vis[x]=1;
 62     for(edge*e=fir[x];e;e=e->next){
 63         if(d[x]==d[e->v]+e->l) dfs(e->v);
 64     }
 65 }
 66 void maintain(){
 67     rep(i,1,n+1) if(vis[i]){
 68         for(edge*e=fir[i];e;e=e->next){
 69             if(vis[e->v]&&d[e->v]==d[i]+e->l) e->f++;
 70         }
 71     }
 72 }
 73 void dp(int x){
 74     if(vis[x]) return;
 75     vis[x]=1;w[x]=0;
 76     for(edge*e=fir[x];e;e=e->next) if(e->f==2){
 77         dp(e->v);
 78         w[x]=max(w[x],w[e->v]+e->l);
 79     }
 80 }
 81 int main(){
 82     n=read();m=read();
 83     u1=read();v1=read();u2=read();v2=read();
 84     rep(i,1,m+1){
 85         int from=read(),to=read(),len=read();
 86         add(from,to,len);
 87     }
 88     dijkstra(u1);dfs(v1);maintain();
 89     clr(vis,0);
 90     dijkstra(u2);dfs(v2);maintain();
 91     clr(vis,0);
 92     rep(i,1,n+1){
 93         for(edge*e=fir[i];e;e=e->next){
 94             if(e->f==2) p[e->v]=1;
 95         }
 96     }
 97     rep(i,1,n+1) if(!p[i]) dp(i);
 98     rep(i,1,n+1) ans=max(ans,w[i]);
 99     clr(p,0);clr(vis,0);clr(w,0);
100     dijkstra(v2);dfs(u2);maintain();
101     rep(i,1,n+1){
102         for(edge*e=fir[i];e;e=e->next){
103             if(e->f==2) p[e->v]=1;
104         }
105     }
106     clr(vis,0);
107     rep(i,1,n+1) if(!p[i]) dp(i);
108     rep(i,1,n+1) ans=max(ans,w[i]);
109     printf("%d\n",ans);
110     return 0;
111 }
View Code

1880: [Sdoi2009]Elaxia的路线

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 898  Solved: 337
[Submit][Status][Discuss]

Description

最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间。Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。 现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

Input

第一行:两个整数N和M(含义如题目描述)。 第二行:四个整数x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ ≤ N),分别表示Elaxia的宿舍和实验室及w**的宿舍和实验室的标号(两对点分别 x1,y1和x2,y2)。 接下来M行:每行三个整数,u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之间有一条路,经过这条路所需要的时间为l。 出出出格格格式式式::: 一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)。

Output

一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)

Sample Input

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

Sample Output

3

HINT

对于30%的数据,N ≤ 100;
对于60%的数据,N ≤ 1000;
对于100%的数据,N ≤ 1500,输入数据保证没有重边和自环。

Source

[Submit][Status][Discuss]
posted @ 2015-11-19 21:10  ChenThree  阅读(196)  评论(0编辑  收藏  举报