题目传送门:ARC090E。

题意简述:

给定一张有 \(N\) 个点 \(M\) 条边的无向图。每条边有相应的边权,边权是正整数。

小 A 要从结点 \(S\) 走到结点 \(T\) ,而小 B 则相反,他要从结点 \(T\) 走到结点 \(S\) 。

小 A 和小 B 走一条边需要的时间都是这条边的边权,不论方向。

问有多少种走法,使得他们俩都走了最短路,但是他们不会相遇,这里相遇指的是在点上或者在边上相遇。

答案对 \(10^9+7\) 取模。

题解:

用 Dijkstra 算法求出以结点 \(S\) 和结点 \(T\) 出发到每个点的最短路和最短路条数。

把从结点 \(S\) 到结点 \(i\) 的最短路记作 \(d1_i\) ,最短路条数对 \(10^9+7\) 取模的结果记作 \(g1_i\)。

把从结点 \(T\) 到结点 \(i\) 的最短路记作 \(d2_i\) ,最短路条数对 \(10^9+7\) 取模的结果记作 \(g2_i\)。

把从结点 \(S\) 到结点 \(T\) 的最短路记作 \(Dist\) 。

考虑用容斥的方法计算答案。答案等于总方案数减去相遇的方案数。总方案数为 \(g1_T^2\) 。

因为走的都是最短路,而且边权是正的,不难证明两人只会相遇一次。

所以只要统计在每个点或者每条边经过的方案数即可。

考虑经过结点 \(i\) 的方案数:
前提是 \(d1_i+d2_i=Dist\) 且 \(d1_i=d2_i\) ,方案数为 \(g1_i^2g2_i^2\) 。

考虑经过边 \(i\overset{d}{\Longleftrightarrow}j\) (其中小 A 从结点 \(i\) 走向结点 \(j\) )的方案数:
前提是 \(d1_i+d+d2_i=Dist\) 且 \(d1_i+d>d2_j\) 且 \(d1_i<d+d2_j\) ,方案数为 \(g1_i^2g2_j^2\) 。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 #define eF(i,u) for(int i=h[u];i;i=nxt[i])
 4 #define Mod 1000000007
 5 using namespace std;
 6 typedef long long ll;
 7 typedef pair<ll,int> pli;
 8
 9 int n,m,S,T;
10 ll Ans;
11 int U[200001],V[200001],D[200001];
12 int h[100001],nxt[400001],to[400001],w[400001],tot;
13 void ins(int x,int y,int z){nxt[++tot]=h[x];to[tot]=y;w[tot]=z;h[x]=tot;}
14
15 ll d1[100001],d2[100001],g1[100001],g2[100001];bool v1[100001],v2[100001];
16 priority_queue<pli,vector<pli>,greater<pli> > pq;
17
18 void Dij(ll*d,ll*g,bool*v,int s){
19     d[s]=0ll;
20     pq.push(pli(0ll,s));
21     g[s]=1;
22     while(!pq.empty()){
23         pli P=pq.top(); pq.pop();
24         int u=P.second; ll du=P.first;
25         if(v[u]||d[u]<du) continue;
26         v[u]=1;
27         eF(i,u){
28             if(d[to[i]]==du+w[i])
29                 g[to[i]]=(g[to[i]]+g[u])%Mod;
30             if(d[to[i]]>du+w[i])
31                 g[to[i]]=g[u],
32                 d[to[i]]=du+w[i], pq.push(pli(d[to[i]],to[i]));
33         }
34     }
35 }
36
37 int main(){
38     int x,y,z;
39     scanf("%d%d",&n,&m);
40     scanf("%d%d",&S,&T);
41     F(i,1,m) scanf("%d%d%d",&x,&y,&z), ins(x,y,z), ins(y,x,z), U[i]=x, V[i]=y, D[i]=z;
42     memset(d1,0x3f,sizeof d1);
43     Dij(d1,g1,v1,S);
44     memset(d2,0x3f,sizeof d2);
45     Dij(d2,g2,v2,T);
46     ll Dist=d1[T];
47     Ans=g1[T]*g1[T]%Mod;
48     F(i,1,n){
49         if(d1[i]+d2[i]==Dist&&d1[i]==d2[i])
50             Ans=(Ans-g1[i]*g1[i]%Mod*g2[i]%Mod*g2[i]%Mod)%Mod;
51     }
52     int u,v,d;
53     F(i,1,m){
54         u=U[i], v=V[i], d=D[i];
55         if(d1[u]+d+d2[v]==Dist && d1[u]+d>d2[v] && d2[v]+d>d1[u]){
56             Ans=(Ans-g1[u]*g2[v]%Mod*g1[u]%Mod*g2[v]%Mod)%Mod;
57         }
58         u=V[i], v=U[i], d=D[i];
59         if(d1[u]+d+d2[v]==Dist && d1[u]+d>d2[v] && d2[v]+d>d1[u]){
60             Ans=(Ans-g1[u]*g2[v]%Mod*g1[u]%Mod*g2[v]%Mod)%Mod;
61         }
62     }
63     printf("%lld",(Ans%Mod+Mod)%Mod);
64     return 0;
65 }

转载于:https://www.cnblogs.com/PinkRabbit/p/10022225.html

AtCoder ARC 090 E / AtCoder 3883: Avoiding Collision相关推荐

  1. 【题解】Atcoder ARC#90 F-Number of Digits

    Atcoder刷不动的每日一题... 首先注意到一个事实:随着 \(l, r\) 的增大,\(f(r) - f(l)\) 会越来越小.考虑暴力处理出小数据的情况,我们可以发现对于左端点 \(f(l) ...

  2. atcoder ARC 084 CD题解

    传送门 C: 给定三组数, 问从每一组中选择一个数使得满足a < b < c 的选法有多少种. 首先我们要知道对于第二个数组中的每一个数, 第三个数组中有多少个大于它的记成cb[i], 并 ...

  3. AtCoder Beginner 217 Solution

    AtCoder Beginner 217 Solution⁡\operatorname{AtCoder\ Beginner\ 217\ Solution}AtCoder Beginner 217 So ...

  4. AtCoder Regular Contest 113 简单题解(AC了 A~C,缺 D~F)剩下的后面几天补一下

    ARC 113 https://atcoder.jp/contests/arc113/tasks.总体来说,自己还是一个菜鸡,还需要继续努力.退化太多了. A题:A*B*C 题目链接 https:// ...

  5. 【AtCoder】ARC090

    C - Candies 前一枚举一个i,求第一行的前i个和第二行从第n个到第i个 代码 #include <bits/stdc++.h> #define fi first #define ...

  6. Atcoder题解与视频集

    开启Atcoder之路 开启Atcoder之路_sortmin的博客-CSDN博客_atcoder怎么用 atcoder心得 atcoder心得_404REN的博客-CSDN博客_atcoder怎么用 ...

  7. AtCoder Beginner Contest 151

    2020-01-12(Sun) 20:00 A Next Alphabet A.Next Alphabet 语法题,输入一个不为z的字母,输出下一位 B Achieve the Goal B.Achi ...

  8. 20180716 [AtCoder]CF697 EASY+SoundHound HARD【值得琢磨实现细节】

    A - Romaji CodeForces - 1008A B - Turn the Rectangles CodeForces - 1008B C - Reorder the Array CodeF ...

  9. Atcoder Regular Contest 92 D Two Sequences F Two Faced Edges 两道神题

    Atcoder 3943 Two Sequences Atcoder 3945 Two Faced Edges Atcoder 3943 Two Sequences 给两个长度为n的数组a,b,求(a ...

最新文章

  1. 人民日报:人工智能,务实发展是正道
  2. linux 列出目录结构6,Linux系统目录结构及文件管理命令
  3. JavaWeb学习之路——SSM框架之SpringMVC(九)
  4. linux中tcp连接内核参数调优somaxconn
  5. 优先队列/单调队列 - 滑动窗口最大值
  6. linux 空间不够了,怎么办?Disk Requirements:At least 11MB more space needed on the / filesystem....
  7. codeforces 110A-C语言解题报告
  8. ROS 教程之 vision: 摄像头标定camera calibration
  9. oracle 新增字段id 并赋值32位_优雅的数据库ID设计
  10. Linux服务器安装JavaWeb环境(一) Jdk,Maven,Nginx,Tomcat
  11. 该行已经属于另一个表 的解决方法
  12. 《剑指offer》面试题15—输出链表中倒数第n个结点
  13. java+cache使用方法_JVM代码缓存区CodeCache原理及用法解析
  14. LeetCode刷题——11. 盛最多水的容器
  15. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_12-删除页面-服务端-接口开发...
  16. Unity 隐藏鼠标
  17. Excel如何在表格内打勾
  18. 《UniBench A Benchmark for Multi-Model Database Management Systems》阅读笔记
  19. 计算机网络安全技术学习总结
  20. 什么是平衡二叉树和平衡二叉树的高度达到O(log2n)最少需要结点数为n

热门文章

  1. shell实现统计浏览次数并将结果保存到文件中
  2. R 中的哪些命令或者包让你相见恨晚?--转载知乎
  3. ruby动态new对象
  4. MySQL利用xtrabackup进行增量备份详细过程汇总
  5. C/C++-style输入输出函数
  6. Redis缓存 ava-Jedis操作Redis,基本操作以及 实现对象保存
  7. Ajax 开发中遇到的乱码问题
  8. 备忘--Sinfors 设备出厂IP
  9. Win10+GTX 1080Ti+Anaconda TensorFlow安装
  10. python的try和except_python的try...except