AtCoder ARC 090 E / AtCoder 3883: Avoiding Collision
题目传送门: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\) 。
#include<bits/stdc++.h>
#define F(i,a,b) for(int i=(a);i<=(b);++i)
#define eF(i,u) for(int i=h[u];i;i=nxt[i])
#define Mod 1000000007
using namespace std;
typedef long long ll;
typedef pair<ll,int> pli; int n,m,S,T;
ll Ans;
int U[],V[],D[];
int h[],nxt[],to[],w[],tot;
void ins(int x,int y,int z){nxt[++tot]=h[x];to[tot]=y;w[tot]=z;h[x]=tot;} ll d1[],d2[],g1[],g2[];bool v1[],v2[];
priority_queue<pli,vector<pli>,greater<pli> > pq; void Dij(ll*d,ll*g,bool*v,int s){
d[s]=0ll;
pq.push(pli(0ll,s));
g[s]=;
while(!pq.empty()){
pli P=pq.top(); pq.pop();
int u=P.second; ll du=P.first;
if(v[u]||d[u]<du) continue;
v[u]=;
eF(i,u){
if(d[to[i]]==du+w[i])
g[to[i]]=(g[to[i]]+g[u])%Mod;
if(d[to[i]]>du+w[i])
g[to[i]]=g[u],
d[to[i]]=du+w[i], pq.push(pli(d[to[i]],to[i]));
}
}
} int main(){
int x,y,z;
scanf("%d%d",&n,&m);
scanf("%d%d",&S,&T);
F(i,,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;
memset(d1,0x3f,sizeof d1);
Dij(d1,g1,v1,S);
memset(d2,0x3f,sizeof d2);
Dij(d2,g2,v2,T);
ll Dist=d1[T];
Ans=g1[T]*g1[T]%Mod;
F(i,,n){
if(d1[i]+d2[i]==Dist&&d1[i]==d2[i])
Ans=(Ans-g1[i]*g1[i]%Mod*g2[i]%Mod*g2[i]%Mod)%Mod;
}
int u,v,d;
F(i,,m){
u=U[i], v=V[i], d=D[i];
if(d1[u]+d+d2[v]==Dist && d1[u]+d>d2[v] && d2[v]+d>d1[u]){
Ans=(Ans-g1[u]*g2[v]%Mod*g1[u]%Mod*g2[v]%Mod)%Mod;
}
u=V[i], v=U[i], d=D[i];
if(d1[u]+d+d2[v]==Dist && d1[u]+d>d2[v] && d2[v]+d>d1[u]){
Ans=(Ans-g1[u]*g2[v]%Mod*g1[u]%Mod*g2[v]%Mod)%Mod;
}
}
printf("%lld",(Ans%Mod+Mod)%Mod);
return ;
}
AtCoder ARC 090 E / AtCoder 3883: Avoiding Collision的更多相关文章
- [AtCoder arc090E]Avoiding Collision
Description 题库链接 给出一张 \(N\) 个节点, \(M\) 条边的无向图,给出起点 \(S\) 和终点 \(T\) .询问两个人分别从 \(S\) 和 \(T\) 出发,走最短路不相 ...
- 【题解】Atcoder ARC#90 E-Avoiding Collision
自己做出来固然开心,但是越发感觉到自己写题的确是很慢很慢了……往往有很多的细节反反复复的考虑才能确定,还要加油呀~ 这道题目的突破口在于正难则反.直接求有多少不相交的不好求,我们转而求出所有相交的.我 ...
- 【题解】Atcoder ARC#90 F-Number of Digits
Atcoder刷不动的每日一题... 首先注意到一个事实:随着 \(l, r\) 的增大,\(f(r) - f(l)\) 会越来越小.考虑暴力处理出小数据的情况,我们可以发现对于左端点 \(f(l) ...
- AtCoder ARC 076E - Connected?
传送门:http://arc076.contest.atcoder.jp/tasks/arc076_c 平面上有一个R×C的网格,格点上可能写有数字1~N,每个数字出现两次.现在用一条曲线将一对相同的 ...
- AtCoder ARC 076D - Built?
传送门:http://arc076.contest.atcoder.jp/tasks/arc076_b 本题是一个图论问题——Manhattan距离最小生成树(MST). 在一个平面网格上有n个格点, ...
- AtCoder ARC 082E - ConvexScore
传送门:http://arc082.contest.atcoder.jp/tasks/arc082_c 本题是一个平面几何问题. 在平面直角坐标系中有一个n元点集U={Ai(xi,yi)|1≤i≤n} ...
- Atcoder ARC 082C/D
C - Together 传送门:http://arc082.contest.atcoder.jp/tasks/arc082_a 本题是一个数学问题. 有一个长度为n的自然数列a[1..n],对于每一 ...
- 【题解】 AtCoder ARC 076 F - Exhausted? (霍尔定理+线段树)
题面 题目大意: 给你\(m\)张椅子,排成一行,告诉你\(n\)个人,每个人可以坐的座位为\([1,l]\bigcup[r,m]\),为了让所有人坐下,问至少还要加多少张椅子. Solution: ...
- 【题解】Atcoder ARC#96 F-Sweet Alchemy
首先,我们发现每一个节点所选择的次数不好直接算,因为要求一个节点被选择的次数大于等于父亲被选择的次数,且又要小于等于父亲被选择的次数 \(+D\).既然如此,考虑一棵差分的树,规定每一个节点被选择的次 ...
随机推荐
- CF235C_Cyclical Quest
很好的一个自动机的题目. 给原串,和若干个询问串.求原串里有多少个不同子串可以通过询问串循环移动得到. 有点类似求两个串的lcs,但是灵活一点. 首先我们把询问串长度扩大一倍,去掉最后一个字符.因为最 ...
- MachineLearning Exercise 4 :Neural Networks Learning
nnCostFunction 消耗公式: a1 = [ones(m,) X]; z2 = a1*Theta1'; pre = sigmoid(a1*Theta1'); a2 = [ones(m,) p ...
- linux eclipse add desktop shortcut with root permission
gedit ~/.local/share/applications/opt_eclipse.desktop sudo apt-get install gksu [Desktop Entry] Type ...
- vyos 基础配置
vyos 基础配置 http://www.lowefamily.com.au/2015/11/29/using-a-vyos-router-with-hyper-v/1/http://thomasvo ...
- 【比赛】NOIP2017 时间复杂度
恶心的模拟题,考场上犯了一堆错误,多组数据清空没清完.数组开小...民间都是50分,结果CCF90.. 考完后随便改改就过了,还好只少了10分,如果真的是50,我估计会疯掉. 因为考场的时候没写好,所 ...
- CF1088F Ehab and a weird weight formula 贪心 倍增
CF1088F Ehab and a weird weight formula 题意 给定一棵树,点有点权,其中这棵树满足除了权值最小的点外,每个点至少有一个点权小于它的相邻点. 要求你重新构建这棵树 ...
- 【BZOJ2024】舞会(动态规划,容斥,高精度)
[BZOJ2024]舞会(动态规划,容斥,高精度) 题面 BZOJ 洛谷 题解 这种关系显然要先排序才不会不想影响. 设\(f[i][j]\)表示前\(i\)个女生中,选了\(j\)个女生配对,并且女 ...
- BZOJ 3295 动态逆序对 | CDQ分治
BZOJ 3295 动态逆序对 这道题和三维偏序很类似.某个元素加入后产生的贡献 = time更小.pos更小.val更大的元素个数 + time更小.pos更大.val更小的元素个数. 分别用类似C ...
- BZOJ3112 [Zjoi2013]防守战线 【单纯形】
题目链接 BZOJ3112 题解 同志愿者招募 费用流神题 单纯形裸题 \(BZOJ\)可过 洛谷被卡.. #include<algorithm> #include<iostream ...
- python与pycharm
什么叫自动化测试? 通俗来说,自动化测试就是通过写代码来帮我们测试软件.用来做自动化测试的语言很多,python,Java,php,Go,ruby等.而且软件系统开发语言与自动化测试语言可以不一致.例 ...