BZOJ1880: [Sdoi2009]Elaxia的路线

题意:求最短路最长公共距离。

考虑每一条边,如果满足dis(s1,u)+len+dis(v,t1)==dis(s1,t1) && dis(s2,u)+len+dis(v,t2)==dis(s2,t2) 则该边在公共最短路上

拓扑排序dp下即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1505
 4 #define INF 1e9
 5 int n,m,a[5],dis[5][N],cnt,cnt1,head[N],head1[N],r[N],ans[N],fin;
 6 bool y[N];
 7 struct data{
 8     int num,v;
 9     bool operator < (const data& w)const{
10        return v>w.v;
11     }
12 };
13 priority_queue<data>q;
14 inline int read(){
15     int x=0,f=1; char a=getchar();
16     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
17     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar();
18     return x*f;
19 } 
20 struct edges{
21     int fr,to,v,next;
22 }e[500005],e1[500005];
23 void inser(int u,int v,int c){
24     e[cnt]=(edges){u,v,c,head[u]};head[u]=cnt++;
25     e[cnt]=(edges){v,u,c,head[v]};head[v]=cnt++;
26 }
27 void ins(int u,int v,int c){
28     if(dis[1][u]>dis[1][v]) swap(u,v);
29     e1[cnt1]=(edges){u,v,c,head1[u]};head1[u]=cnt1++; r[v]++;
30 }
31 void dj(int x){
32     dis[x][a[x]]=0; memset(y,0,sizeof(y));q.push((data){a[x],0});
33     int s,to;
34     while(!q.empty()){
35         s=q.top().num; q.pop(); 
36         if(y[s]) continue; y[s]=1;
37         for(int i=head[s];i>=0;i=e[i].next){
38         if(y[e[i].to]) continue; to=e[i].to;
39         if(dis[x][to]>dis[x][s]+e[i].v) dis[x][to]=dis[x][s]+e[i].v,q.push((data){to,dis[x][to]});
40         }
41     }
42 }
43 void topsort(int x){
44     r[x]--;
45     for(int i=head1[x];i>=0;i=e1[i].next){
46         ans[e1[i].to]=max(ans[e1[i].to],ans[x]+e1[i].v);
47         fin=max(ans[e1[i].to],fin);
48         r[e1[i].to]--; if(!r[e1[i].to]) topsort(e1[i].to);
49     }
50 }
51 int main(){
52     n=read(); m=read(); 
53     memset(dis,34,sizeof(dis)); 
54     memset(head,-1,sizeof(head));
55     memset(head1,-1,sizeof(head1));
56     for(int i=1;i<=4;i++) a[i]=read();
57     for(int u,v,c,i=1;i<=m;i++)
58     u=read(),v=read(),c=read(),inser(u,v,c);
59     for(int i=1;i<=4;i++) dj(i);
60     for(int i=0;i<cnt;i+=2){
61         int u=e[i].fr,v=e[i].to;
62         if((dis[1][u]+e[i].v+dis[2][v]==dis[1][a[2]] || dis[1][v]+e[i].v+dis[2][u]==dis[1][a[2]]) && (dis[3][u]+e[i].v+dis[4][v]==dis[3][a[4]] || dis[3][v]+e[i].v+dis[4][u]==dis[3][a[4]]))
63         ins(u,v,e[i].v);
64     }
65     for(int i=1;i<=n;i++)
66     if(!r[i]) topsort(i);
67     printf("%d
",fin);
68     return 0;
69 }
原文地址:https://www.cnblogs.com/enigma-aw/p/6032597.html