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就可以了 ----------- ...
随机推荐
- Server Job: error: String or binary data would be truncated. The statement has been terminated.
"String or binary data would be truncated. The statement has been terminated" most probabl ...
- sql server 系统表系统视图 及作用说明
sql server 系统视图,可分为: 目录视图 兼容性视图 动态管理视图和函数 信息架构视图 复制视图 系统表: sysaltfiles主数据库 保存数据库的文件 sysch ...
- 浅述Oracle分布式事务概念
着系统的复杂性不断增加,我们所面对的分布式系统渐渐增加.分布式文件系统.分布式消息队列系统等等层出不穷,在一些行业特别是互联网行业应用广泛.分布式数据库也是目前使用比较常用的分布式系统之一. 简单来说 ...
- java 修改文件名
// 修改文件名 public static boolean modifyFileName(String serverPath, String oldFileName, String newLogin ...
- Mongodb基本操作之.net
1.下载官方for C#驱动 2.导入2个dll文件 3.连接字符串 <add key="MongoConn" value="mongodb://127.0.0.1 ...
- Android开源项目及库搜集
TimLiu-Android 自己总结的Android开源项目及库. github排名 https://github.com/trending,github搜索:https://github.com/ ...
- python中的model模板中的数据类型
mode对应的类型 见 : https://docs.djangoproject.com/en/1.8/ref/models/fields/ 命令行ipython查看 from django.db i ...
- JS 闭包问题
一.什么是闭包?“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 相信很少有人能直接看懂这句话,因为他描述的太 ...
- IE6双倍margin间距解决方法
虽然现在很少有人在用ie6了,但作为前端人员,是不的不面对的问题. 在ie6中,使用float后的元素,在margin—left,这是你会发现距离和你想的不一样,其他的浏览器又是正常的,增大margi ...
- LINUX 循环fork()
#include <sys/types.h> #include <unistd.h> int main() { for(int i = 0; i < ...