luogu2149 Elaxia的路线 (dijkstra+拓扑dp)

先标记上一个人所有最短路上的边(同时也要标记反向边)

然后拿着另一个人最短路上的边(会构成一个DAG)去做拓扑dp,记从原点到某个点的最大的某个路径的被标记的边的个数

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=1505;
 7 
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1;
10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*neg;
13 }
14 
15 struct Edge{
16     int a,b,l,ne;
17     bool u;
18 }eg[maxn*maxn];
19 int egh[maxn],ect=1;
20 int N,M,s1,s2,t1,t2;
21 int d1[maxn],d2[maxn],ine[maxn],cnt[maxn];
22 bool flag[maxn];
23 priority_queue<pa,vector<pa>,greater<pa> > q;
24 queue<int> q2;
25 
26 inline void adeg(int a,int b,int c){
27     eg[++ect].a=a,eg[ect].b=b,eg[ect].l=c,eg[ect].ne=egh[a],egh[a]=ect;
28 }
29 
30 inline void dijkstra(int *dis,int s){
31     CLR(flag,0);
32     dis[s]=0;q.push(make_pair(0,s));
33     while(!q.empty()){
34         int p=q.top().second;q.pop();
35         if(flag[p]) continue;
36         flag[p]=1;
37         for(int i=egh[p];i;i=eg[i].ne){
38             int b=eg[i].b;
39             if(dis[b]>dis[p]+eg[i].l){
40                 dis[b]=dis[p]+eg[i].l;
41                 q.push(make_pair(dis[b],b));
42             }
43         }
44     }
45 }
46 
47 int main(){
48     //freopen("","r",stdin);
49     int i;
50     N=rd(),M=rd(),s1=rd(),t1=rd(),s2=rd(),t2=rd();
51     for(i=1;i<=M;i++){
52         int a=rd(),b=rd(),c=rd();
53         adeg(a,b,c);adeg(b,a,c);
54     }
55     CLR(d1,127);CLR(d2,127);
56     dijkstra(d1,s1);dijkstra(d2,t1);
57     for(i=2;i<=ect;i++){
58         if(d1[eg[i].a]+eg[i].l+d2[eg[i].b]==d1[t1])
59             eg[i].u=eg[i^1].u=1;
60     }
61     CLR(d1,127),CLR(d2,127);
62     dijkstra(d1,s2);dijkstra(d2,t2);
63     // for(i=1;i<=N;i++) printf("~%d %d %d\n",i,d1[i],d2[i]);
64     for(i=2;i<=ect;i++){
65         if(d1[eg[i].a]+eg[i].l+d2[eg[i].b]==d1[t2])
66             ine[eg[i].b]++;
67     }
68     q2.push(s2);
69     while(!q2.empty()){
70         int p=q2.front();q2.pop();
71         // printf("!%d\n",p);
72         for(int i=egh[p];i;i=eg[i].ne){
73             int b=eg[i].b;
74             if(d1[p]+eg[i].l+d2[eg[i].b]!=d1[t2]) continue;
75             cnt[b]=max(cnt[b],cnt[p]+eg[i].u*eg[i].l);
76             ine[b]--;
77             if(!ine[b]) q2.push(b);
78         }
79     }
80     printf("%d\n",cnt[t2]);
81     return 0;
82 }

猜你喜欢

转载自www.cnblogs.com/Ressed/p/9833363.html