题目大意
给你一张无向连通图,再给你若干个队伍,并给出起点与终点,队伍会从起点出发走最短路到终点,但最短路的数量不一定唯一,因此当队伍在一点可以选择多条边走最短路线时,他们会均匀随机地选择一条边前进。每个队伍会有一个所属的势力,当两个不同的势力的行动轨迹在某点相交时就会发生冲突。试求发生冲突的概率。
分析
考场的我真的是很差劲,最短路图都建错了。所以在此有必要先说明怎么建图。首先当然是先跑一遍最短路(dij),然后再暴力枚举每一条边,假如 d i s [ f [ i ] . t o ] = = d i s [ u ] + f [ i ] . v a l dis[f[i].to] == dis[u] +f[i].val dis[f[i].to]==dis[u]+f[i].val那么就将 i i i这条边加入到一个新图中。然后在新图中再从起点出发,第一遍只跑正向的边,然后再从终点出发只跑反向的边,那么两边都跑到的边就一定能成为最短路的一部分。
然后计算每个点被走到的概率。每个点被走到的概率为所有与它相连的且入度已经为0的点走到它的概率之和。(有点绕,不过可以自己好好想想画画图,还是很容易理解的。),这里一定不能忽略的是入度为零的限制,所以最后要用到一个拓扑。
然后前面都预处理好了之后就可以比较顺利地处理出答案了。
然后这题就ok了,不过感觉放在D1T1有点难了吧。
#include <cstdio>
#include <cstring>
#include <queue>
#define ll long long
using namespace std;
const ll mo = 998244353;
const int N = 3e3 + 10;
const int M = 3e3 + 10;
struct Edge{
int to,next;
} f[M << 2],fs[M << 2],fn[M << 2];
int n,m,k,T,head[N],cnt,dis[N],heads[N],headn[N],deg[N],siz;
bool vis[N];
ll p[N][N << 2],inv[N],pf[N],ans[N],pp[N],ps[N];
queue<int> que;
int read()
{
int x = 0,w = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') w = -1; ch =