bzoj2750: [HAOI2012]Road
Posted Bloodline
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2750: [HAOI2012]Road相关的知识,希望对你有一定的参考价值。
2750: [HAOI2012]Road
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 651 Solved: 302
[Submit][Status][Discuss]
Description
C国有n座城市,城市之间通过m条单向道路连接。一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小。两条最短路不同,当且仅当它们包含的道路序列不同。我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路。现在,这个任务交给了你。
Input
第一行包含两个正整数n、m
接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路
Output
输出应有m行,第i行包含一个数,代表经过第i条道路的最短路的数目对1000000007取模后的结果
Sample Input
4 4
1 2 5
2 3 5
3 4 5
1 4 8
1 2 5
2 3 5
3 4 5
1 4 8
Sample Output
2
3
2
1
3
2
1
建出最短路图。。然后答案就是起点到这个点的最短路径乘以这个点到终点的最短路径。。
但是觉得挺难写的TAT
然后发现了dij的新姿势。。
扔个链接 http://www.cnblogs.com/zyfzyf/p/3995257.html
dijkstra算法可以在算出最短路的同时将点的源点的距离排序,然后按照这个
从前往后枚举在最短路上的边可以得到源点到每个点的最短路的数目,记为a[i]
从后往前枚举在最短路上的边可以得到经过每个点有多少条最短路,记为b[i]
然后对于每条边就是 +=a[e[i].from]*b[e[i].go]
1 #include<bits/stdc++.h> 2 #define rep(i,l,r) for(int i=l;i<=r;++i) 3 #define pa pair<int,int> 4 using namespace std; 5 const int N=5005; 6 typedef long long ll; 7 const ll ccz=1000000007; 8 int head[N],tot,dis[N],u,v,w,n,m,cnt,c[N]; 9 ll a[N],b[N],ans[N]; 10 struct zs{ 11 int to,next,w,id; 12 }e[N]; 13 bool in[N]; 14 inline void ins(int u,int v,int w,int id){ 15 e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w; e[tot].id=id; 16 } 17 inline void run(int s){ 18 priority_queue<pa,vector<pa>,greater<pa> >q; 19 memset(in,0,sizeof in); 20 memset(dis,60,sizeof dis); dis[s]=0; q.push(make_pair(0,s)); 21 cnt=0; 22 while(!q.empty()){ 23 int x=q.top().second; q.pop(); 24 if(in[x]) continue; in[x]=1; c[++cnt]=x; 25 for(int k=head[x];k;k=e[k].next) if(dis[x]+e[k].w<dis[e[k].to]) { 26 dis[e[k].to]=e[k].w+dis[x]; 27 q.push(make_pair(dis[e[k].to],e[k].to)); 28 } 29 } 30 memset(a,0,sizeof a); memset(b,0,sizeof b); 31 rep(i,1,cnt) b[c[i]]=1; 32 a[s]=1; 33 rep(i,1,cnt) for(int k=head[c[i]];k;k=e[k].next) if(dis[c[i]]+e[k].w==dis[e[k].to])(a[e[k].to]+=a[c[i]])%=ccz; 34 for(int i=cnt;i;i--) for(int k=head[c[i]];k;k=e[k].next) if(dis[c[i]]+e[k].w==dis[e[k].to])(b[c[i]]+=b[e[k].to])%=ccz; 35 rep(i,1,n) for(int k=head[i];k;k=e[k].next) if(dis[i]+e[k].w==dis[e[k].to])(ans[e[k].id]+=a[i]*b[e[k].to])%=ccz; 36 } 37 int main(){ 38 scanf("%d%d",&n,&m); 39 rep(i,1,m) scanf("%d%d%d",&u,&v,&w),ins(u,v,w,i); 40 rep(i,1,n) run(i); 41 rep(i,1,m) printf("%lld\\n",ans[i]); 42 }
以上是关于bzoj2750: [HAOI2012]Road的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 2752:[HAOI2012]高速公路(road)(线段树)
BZOJ2752: [HAOI2012]高速公路(road)
BZOJ 2752: [HAOI2012]高速公路(road) [线段树 期望]