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就可以了 ----------- ...
随机推荐
- scroll pagination.js数据重复加载、分页问题
scroll pagination.js数据重复加载.分页问题 解决办法 参考资料: http://blog.csdn.net/dyw442500150/article/details/1753242 ...
- 性能优化之NSDateFormatter
为什么要优化NSDateFormatter? 优化方式有哪些? 为什么要优化NSDateFormatter? 首先,过度的创建NSDateFormatter用于NSDate与NSString之间转换, ...
- 【HPP开发】让所有中小企业拥有自己的APP
HPP hybirdApp或者hbuilderApp, 指通过html,css,js语言开发出ios和android两个版本的APP, 开发效率成倍上升,开发时间大幅缩减,开发成本同样也大大缩减. 移 ...
- @IBDesignable和@IBInspectable
近期一直在看苹果公司提供的两本swift官方教程电子书,一部是<The Swift Programming Language>,还有一部是<Using Swift With Coco ...
- 题目:[NOIP1999]拦截导弹(最长非递增子序列DP) O(n^2)和O(n*log(n))的两种做法
题目:[NOIP1999]拦截导弹 问题编号:217 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发 ...
- 自定义ImageView实现图片手势滑动,多点触摸放大缩小效果
首先呢,还是一贯作风,我们先来看看众多应用中的示例:(这种效果是很常见的,可以说应用的必须品.) 搜狐客户端 ...
- lua 加密
项目要求对lua脚本进行加密,查了一下相关的资料 ,得知lua本身可以使用luac将脚本编译为字节码(bytecode)从而实现加密,试了一下,确实可行.下面是使用原生的lua解释器编译字节码:1.新 ...
- i2c sub system __i2c_board_list/klist_devices/klist_drivers
i2c_devinfo全局链表: __i2c_board_list 用来挂接 i2c_board_info,这个信息用来生成 i2c_client i2c_client 链表: i2c_bus_typ ...
- Ruby与sass 与compass安装
Ruby安装 windows平台下使用Rubyinstaller安装 1) 下载Rubyinstaller 2) 安装Rubyinstaller 记得勾选 add ruby executables ...
- java 位运算权限管控(转载)
这里笔者介绍一种很常用,也比较专业的权限控制思路.这里用java语言描述,其实都差不多的.要换成其他的语言主,自己转一下就可以了.为了方便起见,我们这里定义a^b为:a的b次方.这里,我们为每一个操作 ...