bzoj 2750: [HAOI2012]Road
Description
C国有n座城市,城市之间通过m条单向道路连接。一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小。两条最短路不同,当且仅当它们包含的道路序列不同。我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路。现在,这个任务交给了你。
Input
第一行包含两个正整数n、m
接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路
Output
输出应有m行,第i行包含一个数,代表经过第i条道路的最短路的数目对1000000007取模后的结果
Sample Input
1 2 5
2 3 5
3 4 5
1 4 8
Sample Output
3
2
1
HINT
数据规模
30%的数据满足:n≤15、m≤30
60%的数据满足:n≤300、m≤1000
100%的数据满足:n≤1500、m≤5000、w≤10000
Source
社交网络的加强版。floyd肯定是跑不过了。
首先枚举一个起点开始跑spfa,然后在最短路图上统计答案,(最短路图是DAG)
对于一条在最短路图上的边(x.y),被经过次数是(源点到x的方案数)*(y的后继结点个数)。。。
这个很显然,然后因为是DAG这两个值可以通过拓扑排序或记忆化搜索来解决。
// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int N=100050;
const int Mod=1000000007;
int head[N],to[N],nxt[N],v[N],cnt,n,m;
ll ans[N],dp[N],dp2[N],dis[N],vis[N],du[N];
struct data{
int x,y,w;
}e[N];
struct Data{
int x,w;
};
vector<Data> p[N];
void lnk(int x,int y,int z){
to[++cnt]=y,nxt[cnt]=head[x],v[cnt]=z,head[x]=cnt;
p[y].push_back((Data){x,z});
}
queue<int> Q;
void spfa(int s){
for(int i=1;i<=n;i++) dis[i]=19260817,vis[i]=0;
Q.push(s);vis[s]=1;dis[s]=0;
while(!Q.empty()){
int x=Q.front();Q.pop();vis[x]=0;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(dis[y]>dis[x]+v[i]){
dis[y]=dis[x]+v[i];
if(!vis[y]) Q.push(y),vis[y]=1;
}
}
}
}
int dfs1(int x){
if(dp[x]) return dp[x];
for(int i=0;i<p[x].size();i++){
int y=p[x][i].x;
if(dis[y]==dis[x]-p[x][i].w){du[y]++;(dp[x]+=dfs1(y))%=Mod;}
}
return dp[x];
}
void topsort(){
for(int i=1;i<=n;i++) if(du[i]==0) Q.push(i);
while(!Q.empty()){
int x=Q.front();Q.pop();
for(int i=0;i<p[x].size();i++){
int y=p[x][i].x;
if(dis[y]==dis[x]-p[x][i].w){
du[y]--;dp2[y]+=dp2[x];
if(du[y]==0) Q.push(y);
}
}
}
}
int main(){
freopen("roadsw.in","r",stdin);
freopen("roadsw.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
lnk(e[i].x,e[i].y,e[i].w);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) dp[j]=dp2[j]=0,du[j]=0;
spfa(i);
dp[i]=1;for(int j=1;j<=n;j++) dp[j]=dfs1(j);
for(int j=1;j<=n;j++) dp2[j]=1;topsort();
for(int j=1;j<=m;j++) if(dis[e[j].x]+e[j].w==dis[e[j].y]) (ans[j]+=dp[e[j].x]*dp2[e[j].y])%=Mod;
}
for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
return 0;
}
bzoj 2750: [HAOI2012]Road的更多相关文章
- BZOJ 2750: [HAOI2012]Road( 最短路 )
对于每个点都跑最短路, 然后我们得到了个DAG, 在这DAG上更新每条边的答案. 考虑e(u, v)∈DAG对答案的贡献: 假设从S到u得路径数为A[u], 从v出发到达任意点的路径数为B[v], ...
- bzoj 2750: [HAOI2012]Road【spfa+dfs】
枚举起点做spfa,然后一条边在最短路上的条件是dis[e[i].to]==dis[u]+e[i].va,所以每次spfa完之后,dfs出a[i]表示经过i点的最短路的起点数,b[i]表示经过i点的最 ...
- BZOJ2750: [HAOI2012]Road
2750: [HAOI2012]Road Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 261 Solved: 113[Submit][Status ...
- [HAOI2012]Road
2750: [HAOI2012]Road Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 728 Solved: 349[Submit][Status ...
- BZOJ 2752: [HAOI2012]高速公路(road)( 线段树 )
对于询问[L, R], 我们直接考虑每个p(L≤p≤R)的贡献,可以得到 然后化简一下得到 这样就可以很方便地用线段树, 维护一个p, p*vp, p*(p+1)*vp就可以了 ----------- ...
- BZOJ 2752: [HAOI2012]高速公路(road) [线段树 期望]
2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1219 Solved: 446[Submit] ...
- bzoj 2752: [HAOI2012]高速公路(road)
Description Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站.Y901高速公路是一条由N-1段路以及N个收 ...
- ●BZOJ 2752 [HAOI2012]高速公路(road)
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2752题解: 期望,线段树. 把每个路段看成一个点,那么对于l~R的操作,就可以转化为对l~r ...
- BZOJ 2750 HAOI 2012 Road 高速公路 最短路
题意: 给出一个有向图,求每条边有多少次作为最短路上的边(任意的起始点). 范围:n <= 1500, m <= 5005 分析: 一个比较容易想到的思路:以每个点作为起点,做一次SPFA ...
随机推荐
- 理解MVC入门基础原理
今天,我将开启一个崭新的话题:ASP.NET MVC框架的探讨.首先,我们回顾一下ASP.NET Web Form技术与ASP.NET MVC的异同点,并展示各自在Web领域的优劣点.在讨论之前,我对 ...
- JavaSE之绘制菱形
在JavaSE的算法练习中,绘制菱形是一个比较常见的案例.菱形效果如下图所示: 我们在解决算法问题时,通常情况下,先不要急于马上编码,而是要先观察,找出解决问题的关键所在. 在上图中,我们可以看到,菱 ...
- poj 3431 Expedition 优先队列
poj 3431 Expedition 优先队列 题目链接: http://poj.org/problem?id=2431 思路: 优先队列.对于一段能够达到的距离,优先选择其中能够加油最多的站点,这 ...
- KD-tree详解
转载自:http://blog.csdn.NET/zhjchengfeng5/article/details/7855241 首先来一个问题: 给定平面上一个点集 E ,还有一个定点 V ,怎么在一群 ...
- MySQL 性能优化的最佳20多条经验分享(三)(转)
16. 垂直分割 "垂直分割"是一种把数据库中的表按列变成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的.(以前,在银行做过项目,见过一张表有100多个字段, ...
- 十招让Ubuntu 16.04用起来更得心应手(转)
ubuntu 16.04是一种长期支持版本(LTS),是Canonical承诺发布五年的更新版.也就是说,你可以让这个版本在电脑上运行五年! 这样一来,一开始就设置好显得特别重要.你应该确保你的软件是 ...
- 自动类型安全的.NET标准REST库refit
在SCOTT HANSELMAN 博客上看到一个好东西<Exploring refit, an automatic type-safe REST library for .NET Standar ...
- Windows2000源代码 200+MB
全球最大的软件制造商微软2月12日警告公众称其一部分珍贵的Windows NT和Windows 2000操作系统源代码被泄漏到了一些在线文件共享网络中. 微软称被泄漏的代码只是整个程序的一小部分,但这 ...
- Hadoop 少量map/reduce任务执行慢问题
最近在做报表统计,跑hadoop任务. 之前也跑过map/reduce但是数据量不大,遇到某些map/reduce执行时间特别长的问题. 执行时间长有几种可能性: 1. 单个map/reduce任务处 ...
- LeetCode90:Subsets II
Given a collection of integers that might contain duplicates, nums, return all possible subsets. Not ...