输入输出样例

输入样例#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. Django:(2)视图层&模板层

    视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . ...

  2. java 判断一个字符串是否为纯数字

    if (getUid().matches("[0-9]+")) { Log.v("纯数字");} else { Log.v("非纯数字"); ...

  3. codevs——1276 图标缩放

    1276 图标缩放 2012年CCC加拿大高中生信息学奥赛  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 青铜 Bronze 题解       题目描述 Descriptio ...

  4. JSP国际化设置

    以下内容引用自http://wiki.jikexueyuan.com/project/jsp/internationalization.html: 国际化(i18n):这意味着可以使网站根据访问者的语 ...

  5. Oracle 设置用户密码永不过期

    --1.查看用户的proifle,一般是default select username,profile from dba_users; --2.查看概要文件(default)的密码有效期设置 sele ...

  6. golang 中可变参数的个数

    package main import "fmt" func Greeting(prefix string, who ... string) { fmt.Println(prefi ...

  7. 1072. Gas Station (30)【最短路dijkstra】——PAT (Advanced Level) Practise

    题目信息 1072. Gas Station (30) 时间限制200 ms 内存限制65536 kB 代码长度限制16000 B A gas station has to be built at s ...

  8. i18n国际化的例子

    这个可以点击菜单进行中英文切换,每次切换就可以改变sessionStorage.languge,进行改变i18n的参数lang的值,然后重新调用下就可以了. 工程结构: i18n--| |---css ...

  9. Django打造大型企业官网(二)

    三.项目环境搭建 3.1.创建项目环境和安装包 创建django项目 mkvirtualenv DjangoProject workon DjangoProject pip install -i ht ...

  10. android几个高速打包命令

    在MTK  android4.4 上,有几条命令能够高速打包system uaserdata bootimage,可提高效率. snod:这个命令是能够高速打包system.是不会运行android各 ...