BZOJ2750: [HAOI2012]Road
2750: [HAOI2012]Road
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 261 Solved: 113
[Submit][Status]
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
题解:
60分是社交网络。。。居然还有升级版。。。考场上果断写60分暴力。。
yy了一两天结果发现题看错了。。。
以为是经过某个点的最短路的数目,果断写了topsort+dfs。。。简直不能再sb。。。
贴上我的sb代码
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 500+100
#define maxm 500+100
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
struct edge{int go,next,w;}e[*maxm],e2[*maxm];
ll n,m,k,s,t,tot,q[maxn],d[maxn],head[maxn],head2[maxn],f[maxn],g[maxn],ans[maxn],inp[maxn];
bool v[maxn];
inline void insert(int x,int y,int z)
{
e[++tot].go=y;e[tot].next=head[x];head[x]=tot;e[tot].w=z;
}
inline void insert2(int x,int y)
{
e2[++tot].go=y;e2[tot].next=head2[x];head2[x]=tot;
}
inline void add(ll &x,ll &y)
{
x+=y;
if(x>=mod)x%=mod;
}
void dfs(int x)
{
g[x]=f[x];
for(int i=head2[x];i;i=e2[i].next){dfs(e2[i].go);add(g[x],g[e2[i].go]);};
}
void work(int s)
{
for(int i=;i<=n;++i) d[i]=inf;
memset(v,,sizeof(v));
int l=,r=,x,y;q[]=s;d[s]=;
while(l!=r)
{
x=q[++l];if(l==maxn)l=;v[x]=;
for(int i=head[x];i;i=e[i].next)
if(d[x]+e[i].w<d[y=e[i].go])
{
d[y]=d[x]+e[i].w;
if(!v[y]){v[y]=;q[++r]=y;if(r==maxn)r=;}
}
}
memset(head2,,sizeof(head2));tot=;
memset(inp,,sizeof(inp));
memset(f,,sizeof(f));
memset(g,,sizeof(g));
for1(x,n)
for(int i=head[x],y;i;i=e[i].next)
if(d[x]+e[i].w==d[y=e[i].go])insert2(x,y),inp[y]++;
l=;q[r=]=s;f[s]=;
while(l<r)
{
int x=q[++l];
for(int i=head2[x],y;i;i=e2[i].next)
{
inp[y=e2[i].go]--;
add(f[y],f[x]);
if(!inp[y])q[++r]=y;
}
}
dfs(s);
for1(i,n)add(ans[i],g[i]);ans[s]--;
for1(i,n)cout<<i<<' '<<g[i]<<' '<<f[i]<<endl;
cout<<"TTTTTTTTTTT"<<endl;
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();m=read();int x,y,z;
for1(i,m)x=read(),y=read(),z=read(),insert(x,y,z);
for1(i,n)work(i);
for1(i,n)printf("%lld\n",ans[i]);
return ;
}
纠正题意之后突然发现不会做了 QAQ。。。
膜拜了lyd的代码才知道,居然这么神。。。
dijkstra算法可以在算出最短路的同时将点的源点的距离排序,然后按照这个
从前往后枚举在最短路上的边可以得到源点到每个点的最短路的数目,记为a[i] (也就是我的topsort)
从后往前枚举在最短路上的边可以得到经过每个点有多少条最短路,记为b[i] (也就是我的dfs,我好像写错了23333)
然后对于每条边就是 +=a[e[i].from]*b[e[i].go]
图论题的技巧还有很多,我还太年轻23333
代码:
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 20000
#define maxm 50000
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
struct edge{int go,next,w;}e[*maxm],e2[*maxm];
ll n,m,k,s,t,tot,q[maxn],d[maxn],head[maxn],a[maxn],b[maxn],c[maxn],ans[maxn];
bool v[maxn];
inline void insert(int x,int y,int z)
{
e[++tot].go=y;e[tot].next=head[x];head[x]=tot;e[tot].w=z;
}
inline void add(ll &x,ll y)
{
x+=y;
if(x>=mod)x%=mod;
}
void dijkstra(int s)
{
priority_queue<pa,vector<pa>,greater<pa> >q;
for(int i=;i<=n;i++)d[i]=inf;
memset(v,,sizeof(v));
d[s]=;q.push(make_pair(,s));
int t=;
while(!q.empty())
{
int x=q.top().second;q.pop();
if(v[x])continue;v[x]=;c[++t]=x;
for(int i=head[x],y;i;i=e[i].next)
if(d[x]+e[i].w<d[y=e[i].go])
{
d[y]=d[x]+e[i].w;
q.push(make_pair(d[y],y));
}
}
memset(a,,sizeof(a));a[s]=;
memset(b,,sizeof(b));
for1(i,t)b[c[i]]=;
for1(i,t)
for(int j=head[c[i]],y;j;j=e[j].next)
if(d[c[i]]+e[j].w==d[y=e[j].go])add(a[y],a[c[i]]);
for3(i,t,)
for(int j=head[c[i]],y;j;j=e[j].next)
if(d[c[i]]+e[j].w==d[y=e[j].go])add(b[c[i]],b[y]);
for1(i,n)
for(int j=head[i],y;j;j=e[j].next)
if(d[i]+e[j].w==d[y=e[j].go])add(ans[j],a[i]*b[y]);
}
int main()
{
freopen("roadsw.in","r",stdin);
freopen("roadsw.out","w",stdout);
n=read();m=read();int x,y,z;
for1(i,m)x=read(),y=read(),z=read(),insert(x,y,z);
for1(i,n)dijkstra(i);
for1(i,m)printf("%lld\n",ans[i]);
return ;
}
BZOJ2750: [HAOI2012]Road的更多相关文章
- BZOJ 2750: [HAOI2012]Road( 最短路 )
对于每个点都跑最短路, 然后我们得到了个DAG, 在这DAG上更新每条边的答案. 考虑e(u, v)∈DAG对答案的贡献: 假设从S到u得路径数为A[u], 从v出发到达任意点的路径数为B[v], ...
- [HAOI2012]Road
2750: [HAOI2012]Road Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 728 Solved: 349[Submit][Status ...
- bzoj 2750: [HAOI2012]Road
Description C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它们包含的道路序列不同.我 ...
- 洛谷P2505||bzoj2750 [HAOI2012]道路 && zkw线段树
https://www.luogu.org/problemnew/show/P2505 https://www.lydsy.com/JudgeOnline/problem.php?id=2750 神奇 ...
- bzoj 2750: [HAOI2012]Road【spfa+dfs】
枚举起点做spfa,然后一条边在最短路上的条件是dis[e[i].to]==dis[u]+e[i].va,所以每次spfa完之后,dfs出a[i]表示经过i点的最短路的起点数,b[i]表示经过i点的最 ...
- 【BZOJ】【2750】【HAOI2012】Road
最短路+拓扑序DP orz zyf & lyd 统计每条边在多少条最短路径上……其实可以统计 有多少条最短路径经过了x,以及y出发到达任意一个结束点有多少种走法(沿最短路) 我们可以用Dijk ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ2752: [HAOI2012]高速公路(road)
2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 608 Solved: 199[Submit][ ...
- BZOJ 2752: [HAOI2012]高速公路(road)( 线段树 )
对于询问[L, R], 我们直接考虑每个p(L≤p≤R)的贡献,可以得到 然后化简一下得到 这样就可以很方便地用线段树, 维护一个p, p*vp, p*(p+1)*vp就可以了 ----------- ...
随机推荐
- UVa400.Unix ls
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- hadoop 常用命令
hdfs dfs -mkdir -p /usr/input/hot hdfs dfs -ls / hdfs dfs -ls /usr/input hdfd dfs -cat /usr/ouput/ho ...
- Freemarker生成静态代码实例
1.static.html <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http ...
- mongoose--------ORM数据操作框架
数据关系映射:ORM O:object R:relation M:mapping 把对数据库的操作都封装到对象中,操作了对象,就相当于操作了数据库. 安装: npm install mongoose ...
- jqTransform——学习(1)
官网:http://www.dfc-e.com/metiers/multimedia/opensource/jqtransform/ 转载:http://www.helloweba.com/view- ...
- mnist数据集转换bmp图片
Mat格式mnist数据集下载地址:http://www.cs.nyu.edu/~roweis/data.html Matlab转换代码: load('mnist_all.mat'); type = ...
- [原创作品] 对获取多层json值的封装
今天篇头不废话了,交流加群:164858883 在我们接收后端返回的json数据的时候,在数据缺失的时候,如果直接接收会导致致命错误的发生.可能有些同学会说通常都会有,不用判断直接获取也行.之前我也是 ...
- c#序列化反序列化工具(json,binary,xml)
using System; using System.Text; using System.IO; using System.Runtime.Serialization.Formatters.Bina ...
- 转载:mybatis和hibernate 解析
第一章 Hibernate与MyBatis Hibernate 是当前最流行的O/R mapping框架,它出身于sf.net,现在已经成为Jboss的一部分. Mybatis 是另外一种优秀 ...
- 公告:CSDN博客频道新功能正式上线!
各位尊敬的CSDN用户: 你们好! 为了更好的服务于用户,CSDN博客最新推出如下功能: 1.取消开通博客3天才能发布博文的限制,博客开通之后即可发表博文 2.博客文章增加自定义摘要功能 在发表 ...