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][ ...
随机推荐
- Luogu P4550 收集邮票
题目链接:Click here Solution: 本题直接推价格似乎很难,考虑先从购买次数入手 设购买次数\(g(i)\)为当前有\(i\)种不同的邮票,要买到\(n\)种的期望购买次数 可以由期望 ...
- 网络相关辅助类NetUtils
package yqw.java.util; import java.net.NetworkInterface;import java.util.ArrayList;import java.util. ...
- 《Effective Java》读书笔记 - 7.方法
Chapter 7 Methods Item 38: Check parameters for validity 直接举例吧: /** * ...其他的被我省略了 * @throws Arithmet ...
- leetcode-mid-dynamic programming-55. Jump Game
mycode 71.47% 思路: 既然要到达终点,那么俺就可以倒推,要想到达n,可以有以下情况 1)到达n-1,然后该位置最少可以走一步 2)到达n-2,然后该位置最少可以走两步 3)到达n-3, ...
- 十三、RF中对json的解析
A.需要安装的库 1.RequestsLibrary,安装命令:pip2 install requests 2.HttpLibrary,安装命令:pip2 install robotframework ...
- 阶段3 1.Mybatis_12.Mybatis注解开发_5 mybatis注解建立实体类属性和数据库表中列的对应关系
创建新项目,一对多 复制刚才关闭的项目的文件 复制到们的新项目里面 复制包的依赖 删减相关代码.只保留这三个查询的方法 模糊查询改成传统的占位符的方式 之前是可以自定义实体类的属性字段,和数据库的字典 ...
- 32 位bitmap 内存存储 顺序 bgra 前3位 与23位一致。 都是 bgr 呵呵 与rgb 相反
32 位bitmap 内存存储 顺序 bgra 前3位 与23位一致. 都是 bgr 呵呵 与rgb 相反
- 我在DBGridEh增加一栏复选框及对应操作的解决方案
最近客户有个需求,要求对单据列表里指定的单据进行批量审核,很自然的,我想到了在DBGridEh增加一栏复选框的列,审核时遍历所有单据,将打了勾的单据审核就可以了.查阅了网上很多文章,不外有2个方案,1 ...
- 【Linux 应用编程】进程管理 - 进程间通信IPC之共享内存 mmap
IPC(InterProcess Communication,进程间通信)是进程中的重要概念.Linux 进程之间常用的通信方式有: 文件:简单,低效,需要代码控制同步 管道:使用简单,默认阻塞 匿名 ...
- Django 基于角色的权限控制
有一种场景, 要求为用户赋予一个角色, 基于角色(比如后管理员,总编, 编辑), 用户拥有相应的权限(比如管理员拥有所有权限, 总编可以增删改查, 编辑只能增改, 有些页面的按钮也只有某些角色才能查看 ...