[Code+#1]大吉大利,晚上吃鸡!
输入输出样例
输入样例#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]大吉大利,晚上吃鸡!的更多相关文章
- GMA Round 1 大吉大利,晚上吃鸡
传送门 大吉大利,晚上吃鸡 新年走亲访友能干点啥呢,咱开黑吃鸡吧. 这里有32个人,每个人都可能想玩或者不想玩,这样子一共有$2^{32}$种可能.而要开黑当然得4人4人组一队(四人模式),所以说如果 ...
- [BZOJ5109]大吉大利,晚上吃鸡!
[BZOJ5109]大吉大利,晚上吃鸡! 题目大意: 一张\(n(n\le5\times10^4)\)个点\(m(m\le5\times10^4)\)条边的无向图,节点编号为\(1\)到\(n\),边 ...
- 【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡! 最短路+拓扑排序+DP
[BZOJ5109][CodePlus 2017]大吉大利,晚上吃鸡! Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏 ...
- bzoj5109: [CodePlus 2017]大吉大利,晚上吃鸡!
Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏中,皮皮 和毛毛最喜欢做的事情就是堵桥,每每有一个好时机都能收到不少的快 ...
- 「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡!(dij+bitset)
从S出发跑dij,从T出发跑dij,顺便最短路计数. 令$F(x)$为$S$到$T$最短路经过$x$的方案数,显然这个是可以用$S$到$x$的方案数乘$T$到$x$的方案数来得到. 然后第一个条件就变 ...
- BZOJ5109 CodePlus 2017大吉大利,晚上吃鸡!(最短路+拓扑排序+bitset)
首先跑正反两遍dij求由起点/终点到某点的最短路条数,这样条件一就转化为f(S,A)*f(T,A)+f(S,B)*f(T,B)=f(S,T).同时建出最短路DAG,这样图中任何一条S到T的路径都是最短 ...
- 「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡!
n<=50000,m<=50000的图,给s和t,问有多少点对$(a,b)$满足 嗯. 不会. 首先最短路DAG造出来,然后两个条件转述一下:条件一,$N_a$表示从s到t经过a的路径,$ ...
- [BZOJ5109/CodePlus2017]大吉大利,晚上吃鸡!
Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏中,皮皮和毛毛最喜欢做的事情就是堵桥,每每有一个好时机都能收到不少的快递 ...
- luogu4061 大吉大利,晚上吃鸡!
链接 最短路径\(dag\),一道好题. 题目大意:求一张图中满足下列要求的点对\((i,j)\)数量: 所有最短路径必定会经过 \(i\) 点和 \(j\) 点中的任意一点. 不存在一条最短路同时经 ...
随机推荐
- Codeforces Beta Round #85 (Div. 1 Only) C (状态压缩或是数学?)
C. Petya and Spiders Little Petya loves training spiders. Petya has a board n × m in size. Each cell ...
- openjudge1944 吃糖果
描述名名的妈妈从外地出差回来,带了一盒好吃又精美的巧克力给名名(盒内共有 N 块巧克力,20 > N >0).妈妈告诉名名每天可以吃一块或者两块巧克力.假设名名每天都吃巧克力,问名名共有多 ...
- Python基础之 二
字符编码: 二进制记录:128 64 32 16 8 4 2 1 1 1 1 1 1 1 1 1 = 8位 ascii 编码:占1个字节8位,只能表示256个符号,主要用于显示英语和其 ...
- 创建Django项目(五)——URL配置和视图
2013-08-07 20:02:10| 1.新建blog的URL文件 在blog目录下新建文件"urls.py" : # -*- coding: ...
- 深入理解hadoop(一)
hadoop 前世今生 hadoop最早起源于开源收缩引擎nutch,由dong cutting 贡献,但由于nutch最初的设计不能解决数10亿级别的文件存储和索引而遇到了严重的可扩展性问题,直到 ...
- hibernate dynamic-update="true"属性不起作用原因(转载)
原文地址: https://yan-sa.iteye.com/blog/1913684 由于我在action层使用了注解多例@Scope("prototype"),而在dao层默认 ...
- Python/Java程序员面试必备常用问题解析与答案
转自AI算法联盟,理解python技术问题,以及一些常见的java面试中经常遇到的问题,这些面试问题分为四类: 是什么(what) 如何做(how) 说区别/谈优势(difference) 实践操作( ...
- Property 'sqlMapClient' is required
继承SqlMapClientDaoSupport类的类里面添加如下代码 @Resource(name = "sqlMapClient") private SqlMapClient ...
- Python标准库:内置函数tuple([iterable])
本函数实现从可迭代对象生成一个元组对象返回.元组对象是一个不可改动的列表对象. 样例: #tuple() print(tuple([1, 2, 3])) print(tuple((1, 2, 3))) ...
- DES加密算法的C++实现
<信息安全技术>这门课又在讲 DES 加密算法了,以前用纯C写过一次,这次我用 C++ 重新写了一个,写篇文章以备后用.本文介绍了 DES 算法加密的大致步骤和整体流程. 一.DES算法原 ...