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][ ...
随机推荐
- vscode匹配括号插件
给大家推荐一个vscode匹配括号的插件: Bracket Pair Colorizer.超级好用哦
- postman导入接口
给大家说一个poatman导入接口的好办法,平常要是想在postman上模拟接口,如果复杂的很难配,其实有一个很简单的方法: 现在我模拟一下百度搜索时历史记录的接口: 点击Copy as cUrl 然 ...
- jenkins启动tomcat失败的解决方法
在网上看了都说是加BUILDID, 但是我加了之后,还是启动不成功. 执行了下面2个步骤: 1.在远程服务器的启动脚本里,用nohup来运行启动命令 nohup ./*.start.${prg}.sh ...
- Selenium 详解CSS定位
xpath定位是“屠龙刀”,那CSS定位就是"倚天剑了",相对xpath来说,具有语法简单,定位速度快等优点 一.属性定位 1.可以通过元素的id,class,tag标签这三个属性 ...
- SRCNN 卷积神经网络
2019-05-19 从GitHub下载了代码(这里) 代码量虽然不多,但是第一次学,花了时间还是挺多的.根据代码有跑出结果(基本没有改),但是对于数据集的处理还是看的很懵逼,主要是作者的实现都是用类 ...
- oracle em启动问题
这种情况出现的可能性是(1)主机IP地址改变,(2)主机名改变,(3)移植到全新的主机,(4)监听程序未启动,5)oracle服务也检查一下 关于orcl的启动: emctl start dbcons ...
- Java 有几种修饰符?分别用来修饰什么
4种修饰符 访问权限 类 包 子类 其他包 public ∨ ∨ ∨ ∨ protect ∨ ∨ ∨ × default ∨ ∨ ...
- 目标双站定位仿真C++代码
point-position2 初步完善版. 不再使用eigen库,行列式直接计算得出结果.判断共面异面分别处理. 先提取双站获得图像的匹配特征点,由双站位置信息解析目标位置. // point-po ...
- EDM案例讲解:Mouth foods的EDM邮件营销
你可能没有听说过Mouth foods,它是一个美味产品的在线市场.作为一个日益增长的企业,他们知道电子邮件的重要性,因为在此之前他们通过电子邮件真正找到了企业品牌中的自我,这就是为什么他们认为电子邮 ...
- Oracle.DataAccess.Client.OracleCommand”的类型初始值设定项引发异常
Oracle.ManagedDataAccess.dll 连接Oracle数据库不需要安装客户端 最开始,连接Oracle 数据是需要安装客户端的,ado.net 后来由于微软未来不再支持 Syste ...