P2505 [HAOI2012]道路
统计每条边被最短路经过几次,点数不大,考虑计算以每个点为起点时对其他边的贡献
对于某个点 $S$ 为起点的贡献,首先跑一遍最短路,建出最短路的 $DAG$
考虑 $DAG$ 上的某条边被以 $S$ 为起点的最短路经过的方案数,设此边为 $(u,v)$ ,那么方案数就是 $S$ 到 $u$ 的方案数,乘上 $v$ 到后面各点的方案数
$S$ 到 $u$ 的方案数可以按拓扑序 $dp$ 一遍得到,$v$ 到后面各点的方案数可以建反图再跑一遍 $dp$
然后就可以计算起点 $S$ 对各条边的贡献,对每个点作为起点分别计算贡献即可
具体实现看代码,挺简单的
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=,M=1e4+,mo=1e9+;
inline int fk(int x) { return x>=mo ? x-mo : x; }
int n,m;
ll ans[M];
int fir[N],from[M<<],to[M<<],val[M<<],id[M<<],cntt;
inline void add(int a,int b,int c,int d)
{
from[++cntt]=fir[a]; fir[a]=cntt;
to[cntt]=b; val[cntt]=c; id[cntt]=d;
}
int dis[N];
struct dat {
int x,d;
dat (int a=,int b=) { x=a,d=b; }
inline bool operator < (const dat &tmp) const {
return d>tmp.d;
}
};
priority_queue <dat> Q;
void Dijk(int S)//求以S为起点到各个点的最短路
{
for(int i=;i<=n;i++) dis[i]=mo;
Q.push(dat(S,)); dis[S]=;
while(!Q.empty())
{
dat x=Q.top(); Q.pop(); if(dis[x.x]!=x.d) continue;
for(int i=fir[x.x];i;i=from[i])
{
int &v=to[i]; if(dis[v]<=x.d+val[i]) continue;
dis[v]=x.d+val[i]; Q.push(dat(v,dis[v]));
}
}
}
vector <int> V[N],G[N];//V存DAG
int du[N],f[N],g[N];//入度,S到各个点的方案,各个点到后面其他点的方案
void Tuopu(int *F,bool type)//DAG上dp算方案数
{
queue <int> q;
for(int i=;i<=n;i++) if(!du[i]) q.push(i),F[i]=;
if(type) for(int i=;i<=n;i++) F[i]=;
while(!q.empty())
{
int x=q.front(),len=V[x].size(); q.pop();
for(int i=;i<len;i++)
{
int &v=V[x][i]; F[v]=fk(F[v]+F[x]);
du[v]--; if(!du[v]) q.push(v);
}
}
}
void calc(int S)//计算以S为起点的贡献
{
for(int i=;i<=n;i++)
du[i]=f[i]=g[i]=,V[i].clear(),G[i].clear();
for(int i=;i<=n;i++)
for(int j=fir[i];j;j=from[j])
{
int &v=to[j]; if(dis[v]!=dis[i]+val[j]) continue;
V[i].push_back(v); du[v]++;
}
Tuopu(f,);
for(int i=;i<=n;i++) G[i]=V[i],V[i].clear();
for(int i=;i<=n;i++)
for(int j=G[i].size()-;j>=;j--) V[G[i][j]].push_back(i),du[i]++;//建反图
Tuopu(g,);
for(int i=;i<=n;i++)
for(int j=fir[i];j;j=from[j])
{
int &v=to[j]; if(dis[v]!=dis[i]+val[j]) continue;
ans[id[j]]=fk(ans[id[j]] + 1ll*f[i]*g[v]%mo );//注意long long
}
}
int main()
{
n=read(),m=read(); int a,b,c;
for(int i=;i<=m;i++)
a=read(),b=read(),c=read(),add(a,b,c,i);
for(int i=;i<=n;i++) Dijk(i),calc(i);
for(int i=;i<=m;i++) printf("%lld\n",ans[i]);
return ;
}
P2505 [HAOI2012]道路的更多相关文章
- 洛谷 P2505 [HAOI2012]道路 解题报告
P2505 [HAOI2012]道路 题目描述 C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它 ...
- 洛谷P2505 [HAOI2012]道路(最短路计数)
传送门 早上模拟赛考这题,结果竟然看错题目了orz 然后下午看完题解自己做的时候空间开小了白WA了好久orz 首先,如果以$S$为起点,一条边$(u,v)$在最短路上,则$dis[u]+edge[i] ...
- JZYZOJ1525 HAOI2012道路 堆优化的dijkstra+pair
From Tyvj Guest ☆[haoi2012]道路 描述 Description C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当 ...
- 洛谷P2505||bzoj2750 [HAOI2012]道路 && zkw线段树
https://www.luogu.org/problemnew/show/P2505 https://www.lydsy.com/JudgeOnline/problem.php?id=2750 神奇 ...
- [HAOI2012]道路
题目描述 C国有n座城市,城市之间通过m条[b]单向[/b]道路连接.一条路径被称为最短路,当且仅当不存在从 它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它们包含的道路序列不同. ...
- [HAOI2012]道路(最短路DAG上计数)
C国有n座城市,城市之间通过m条[b]单向[/b]道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它们包含的道路序列不同.我们需要对每 ...
- 题解 [HAOI2012]道路
题目传送门 题目大意 给出一个 \(n\) 个点 \(m\) 条边的有向图,问每一条边在多少个最短路径中出现. \(n\le 1500,m\le 5000\) 思路 算我孤陋寡闻了... 很显然,我们 ...
- test20190829 神大校赛模拟
100+100+0=200,聪明搬题人题面又出锅了. 最短路径(path) 给定有向图,包含 n 个节点和 m 条有向边. 一条A 到 B 的路径是最短路径当且仅当不存在另一条从A 到 B 的路径比它 ...
- BZOJ2752: [HAOI2012]高速公路(road)
2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 608 Solved: 199[Submit][ ...
随机推荐
- SQLite为何要用C语言来开发?
SQLite 选择 C 语言的理由是?为什么不选择 Go 或者 Rust? C 语言是最好的 SQLite 在 2000 年 5 月 29 日发布,并一直使用 C 语言实现.C 语言一直是实现 SQL ...
- 2019hdu多校 Keen On Everything But Triangle
Problem Description N sticks are arranged in a row, and their lengths are a1,a2,...,aN. There are Q ...
- Kubernetes Deployment故障排除图解指南
个人K8s还在学习中,相关博客还没有写,准备学第二遍再开始学,发现这篇文章挺好,先转载一下. 原创: 白明的赞赏账户 下面是一个示意图,可帮助你调试Kubernetes Deployment(你可以 ...
- 南京网络赛 E K Sum
K Sum 终于过了这玩意啊啊啊==== 莫比乌斯反演,杜教筛,各种分块,积性函数怎么线性递推还很迷==,得继续研究研究 #include<bits/stdc++.h> using nam ...
- [LeetCode]-algorithms-Reverse Integer
Reverse digits of an integer. If the integer's last digit is 0, what should the output be? ie, cases ...
- java中 Excel表实现数据导入导出
需要引入依赖: <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> < ...
- java中的过滤器 --Filter
package filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.Filter ...
- CNN中感受野的理解
本文摘自看完还不懂卷积神经网络“感受野”?那你来找我 作者:程序_小白链接:https://www.jianshu.com/p/9305d31962d8 一.到底什么是“感受野”(接受野Recepti ...
- 【洛谷T89353 【BIO】RGB三角形】
题目链接 这个题我一开始显然直接暴力 然后30分(但是应用数据分治的我通过复杂度判断并且其余输出0的能力硬生生的拿下了60分) 主要还是讲正解 这里有一个结论 这样一个图,红点的值可以通过两个黄点来判 ...
- ES6数值的拓展
二进制和八进制表示法 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示. 如果要将0b和0o前缀的字符串数值转为十进制,要使用Number方法 Number(' ...