输入输出样例

输入样例#1:

7 7 1 7

1 2 2

2 4 2

4 6 2

6 7 2

1 3 2

3 5 4

5 7 2

输出样例#1:

6

输入样例#2:

5 5 1 4

1 2 1

1 3 1

2 4 1

3 4 1

4 5 1

输出样例#2:

3

输入样例#3:

6 7 1 4

1 2 1

1 3 1

2 4 1

3 4 1

4 5 1

1 6 2

6 4 2

输出样例#3:

5


这题好码农啊 写挂了好多发

这题就是让我们找出符合条件的点对的数量

符合条件的点对能够覆盖所有从\(S~T\)的最短路径并且必须不在同一条最短路径上

那么我们可以先正反跑两边最短路记录通过每个点的最短路数目

那么显然只有点对\(<u,v>\)符合\(f[u]+f[v]=f[T]\)才是合法的

然后就该考虑如何处理不在同一条最短路径上了

我们可以在跑最短路的时候顺便记录下一条从S~T的最短路径

然后可以对这个最短路径进行编号\(1~Num\)

然后我们要统计每个不在找出的这条最短路径上的每个点能对我们找出的这条最短路上的哪些点产生影响

显然能影响的点是我们找到的最短路径上的一段连续的点

因为如果这个点能在走最短路径的时候被u走到,那么一定能被u的前驱/后继走到

如果没有最短路径经过这个点,那么这个点一定会对我们找出的最短路径上的所有点产生影响

所以我们只需要求有最短路径经过的点对找到的最短路径上的点的贡献

直接求这段连续的点比较困难,我们可以正反两遍拓扑排序求

我们只需要枚举每条边\(<u,v>\)然后查看这条边是不是最短路径经过的边,如果是就\(++d[v]\)

这样我们就可以拓扑排序了

拓扑的时候用\(l[u]/r[u]\)来更新\(l[v]/r[v]\)

最后扫一遍就好了

#include<map>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
# define LL long long
const int M = 50005 ;
const LL INF = 1e15 ;
using namespace std ;
inline int read() {
char c = getchar() ; int x = 0 , w = 1 ;
while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
return x * w ;
}
bool vis[M] ;
int n , m , S , T , upp ;
int hea[M] , num , Nxt[M] , Num ;
int p[M] , l[M] , r[M] , d[M] ;
LL dis[2][M] , f[2][M] , e[M] , Ans ;
map < LL , int > t ;
vector < int > pl[M] , pr[M] ;
struct Node { int id ; LL v ; } ;
struct E { int Nxt , to ; LL dis ; } edge[M << 1] ;
inline bool operator < (Node a , Node b) { return a.v > b.v ; }
inline void add_edge(int from , int to , int dis) {
edge[++num].Nxt = hea[from] ; edge[num].to = to ;
edge[num].dis = dis ; hea[from] = num ;
}
inline void dijkstra(int t , int S) {
priority_queue < Node > q ;
memset(vis , false , sizeof(vis)) ;
memset(dis[t] , 63 , sizeof(dis[t])) ;
f[t][S] = 1 ; dis[t][S] = 0 ;
q.push((Node) { S , 0 }) ;
while(!q.empty()) {
int u = q.top().id ; q.pop() ;
if(vis[u]) continue ; vis[u] = true ;
for(int i = hea[u] ; i ; i = edge[i].Nxt) {
int v = edge[i].to ;
if(dis[t][v] > dis[t][u] + edge[i].dis) {
f[t][v] = f[t][u] ;
dis[t][v] = dis[t][u] + edge[i].dis ;
Nxt[v] = u ;
if(vis[v]) continue ;
q.push((Node) { v , dis[t][v] }) ;
}
else if(dis[t][v] == dis[t][u] + edge[i].dis)
f[t][v] += f[t][u] ;
}
}
}
inline void Topsort(int t) {
queue < int > q ;
for(int u = 1 ; u <= n ; u ++)
for(int i = hea[u] ; i ; i = edge[i].Nxt) {
int v = edge[i].to ;
if(dis[t][v] + dis[t ^ 1][u] + edge[i].dis == upp)
++d[v] ;
}
while(!q.empty()) {
int u = q.front() ; q.pop() ;
for(int i = hea[u] ; i ; i = edge[i].Nxt) {
int v = edge[i].to ;
if(dis[t][v] + dis[t ^ 1][u] + edge[i].dis == upp) {
-- d[v] ;
if(d[v] == 0) q.push(v) ;
if(!t) l[v] = max(l[v] , l[u]) ;
else r[v] = min(r[v] , r[u]) ;
}
}
}
}
int main() {
n = read() ; m = read() ; S = read() ; T = read() ;
for(int i = 1 , u , v , w ; i <= m ; i ++) {
u = read() , v = read() , w = read() ;
add_edge(u , v , w) ; add_edge(v , u , w) ;
}
dijkstra(0 , S) ;
if(dis[0][T] > INF) { printf("%lld\n" , 1LL * n * (n - 1) / 2) ; return 0 ; }
dijkstra(1 , T) ;
upp = dis[0][T] ;
Nxt[T] = 0 ;
for(int i = S ; i ; i = Nxt[i]) {
p[++Num] = i ;
l[i] = Num + 1 , r[i] = Num - 1 ;
}
for(int i = 1 ; i <= n ; i ++)
if(l[i] == r[i] && l[i] == 0)
l[i] = 1 , r[i] = Num ;
Topsort(0) ; Topsort(1) ;
for(int i = 1 ; i <= n ; i ++) {
if(dis[0][i] + dis[1][i] == upp)
e[i] = f[0][i] * f[1][i] ;
if(l[i] > r[i]) continue ;
pl[l[i]].push_back(i) ;
pr[r[i]].push_back(i) ;
}
for(int i = 1 ; i <= Num ; i ++) {
for(int j = 0 ; j < pl[i].size() ; j ++)
++t[e[pl[i][j]]] ;
Ans += t[e[T] - e[p[i]]] ;
for(int j = 0 ; j < pr[i].size() ; j ++)
--t[e[pr[i][j]]] ;
}
printf("%lld\n",Ans) ;
return 0 ;
}

[Code+#1]大吉大利,晚上吃鸡!的更多相关文章

  1. GMA Round 1 大吉大利,晚上吃鸡

    传送门 大吉大利,晚上吃鸡 新年走亲访友能干点啥呢,咱开黑吃鸡吧. 这里有32个人,每个人都可能想玩或者不想玩,这样子一共有$2^{32}$种可能.而要开黑当然得4人4人组一队(四人模式),所以说如果 ...

  2. [BZOJ5109]大吉大利,晚上吃鸡!

    [BZOJ5109]大吉大利,晚上吃鸡! 题目大意: 一张\(n(n\le5\times10^4)\)个点\(m(m\le5\times10^4)\)条边的无向图,节点编号为\(1\)到\(n\),边 ...

  3. 【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡! 最短路+拓扑排序+DP

    [BZOJ5109][CodePlus 2017]大吉大利,晚上吃鸡! Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏 ...

  4. bzoj5109: [CodePlus 2017]大吉大利,晚上吃鸡!

    Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏中,皮皮 和毛毛最喜欢做的事情就是堵桥,每每有一个好时机都能收到不少的快 ...

  5. 「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡!(dij+bitset)

    从S出发跑dij,从T出发跑dij,顺便最短路计数. 令$F(x)$为$S$到$T$最短路经过$x$的方案数,显然这个是可以用$S$到$x$的方案数乘$T$到$x$的方案数来得到. 然后第一个条件就变 ...

  6. BZOJ5109 CodePlus 2017大吉大利,晚上吃鸡!(最短路+拓扑排序+bitset)

    首先跑正反两遍dij求由起点/终点到某点的最短路条数,这样条件一就转化为f(S,A)*f(T,A)+f(S,B)*f(T,B)=f(S,T).同时建出最短路DAG,这样图中任何一条S到T的路径都是最短 ...

  7. 「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡!

    n<=50000,m<=50000的图,给s和t,问有多少点对$(a,b)$满足 嗯. 不会. 首先最短路DAG造出来,然后两个条件转述一下:条件一,$N_a$表示从s到t经过a的路径,$ ...

  8. [BZOJ5109/CodePlus2017]大吉大利,晚上吃鸡!

    Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏中,皮皮和毛毛最喜欢做的事情就是堵桥,每每有一个好时机都能收到不少的快递 ...

  9. luogu4061 大吉大利,晚上吃鸡!

    链接 最短路径\(dag\),一道好题. 题目大意:求一张图中满足下列要求的点对\((i,j)\)数量: 所有最短路径必定会经过 \(i\) 点和 \(j\) 点中的任意一点. 不存在一条最短路同时经 ...

随机推荐

  1. [luoguP2709] 小B的询问(莫队)

    传送门 个数 1 2 3 4 5 答案 1 4 9  16 25 做差 1 3 5 7 9 显然增加一个数只需要增加 ton[a[x]] << 1 | 1 即可 减去一个数也减去这个 注意 ...

  2. Flask(2):登陆验证

    装饰器补充: import functools def auth(func): @functools.wraps(func) # 作用:把原函数的原信息封装到 inner 中 def inner(*a ...

  3. spring-session(一)揭秘

    前言 在开始spring-session揭秘之前,先做下热脑(活动活动脑子)运动.主要从以下三个方面进行热脑: 为什么要spring-session 比较traditional-session方案和s ...

  4. Linux下汇编语言学习笔记6 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  5. [bzoj2527][Poi2011]Meteors_整体二分_树状数组

    Meteors bzoj-2527 Poi-2011 题目大意:题目链接. 注释:略. 想法: 首先答案可以离线,且具有单调性. 这里的单调性就是随着时间的推移,每个国家收集的陨石数增加. 不难想到整 ...

  6. P1334 瑞瑞的木板 洛谷

    https://www.luogu.org/problem/show?pid=1334 题目描述 瑞瑞想要亲自修复在他的一个小牧场周围的围栏.他测量栅栏并发现他需要N(1≤N≤20,000)根木板,每 ...

  7. <项目><day11>查看用户浏览过的商品

    <项目>查看用户浏览过的商品 1.创建一个entity包储存实体对象 1.1创建一个Product的类存储实体对象 对象具有以下属性,并添加set和get方法,含参和不含参的构造方法,to ...

  8. 二 hbase

    Hbase 本文介绍Hbase.但本文的前提是假设你已经读过Google的BigTable论文. Introduction Hbase 是基于Google Big Table用java实现的分布式,列 ...

  9. crontab not running

    there are mutliple ways to describle this issue 1. crontab not running 2. crontab not running and no ...

  10. MySQL 高可用架构在业务层面的分析研究

    )读多写少 虚线表示跨机房部署,比方电子商务系统.一个Master既有读也有些写.对读数据一致性须要比較重要的.读要放在Master上面. M(R)仅仅是一个备库.仅仅有M(WR)挂了之后,才会切换到 ...