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 }