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就可以了 ----------- ...
随机推荐
- java随机数生成器
一.java.lang.Math.Random 调用这个Math.Random()函数能够返回带正号的double值,取值范围是[0.0,1.0)的左闭右开区间,并在该范围内(近似)均匀分布. 二.j ...
- 【C#正则基础】正则表达式
1. 代表任意多个字符:(.*?)2. 代表网页里的<body>*</body>任意的标签内容,替换以后网页源码就只剩纯文本:<[^>]*>3. 代表网页中的 ...
- Matplotlib下载地址
http://www.lfd.uci.edu/~gohlke/pythonlibs/#matplotlib
- ICE 介绍及实现
.ICE是什么? ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通信引擎,是一个面向对象的中间件,使我们能够 ...
- dsadm-dsconf数据导入导出
cd instance-path/ds6/bin #注意黄色参数修改为跟实际环境一致 -c,--accept-cert Does not ask for confirmation before a ...
- 判断http 请求来自于手机还是PC
首先收集了部分客户端请求头部信息如下 iPhone微信: User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) App ...
- saltstack对递归依赖条件(死循环依赖)的处理
本文将对saltstack中状态文件中require条件产生死循环的情形进行简单的测试和分析 测试思路: 写一个包含递归依赖条件的状态文件,进行测试: A依赖于B B依赖于C ...
- sqlserver中的序列
序列是由用户定义的绑定到架构的对象.序列依据定义的间隔按升序或降序生成,并可配置为用尽时重新启动(循环).序列不与特定表关联.序列与表之间的关系由应用程序进行控制. 创建序列的语法: CREATE S ...
- iOS字体 UIFont 字体名字大全
打印所有的字体 NSArray *familyNames = [UIFont familyNames];//所有的家族名称 for(NSString *familyName in familyName ...
- 使用jQuery操作元素的属性与样式
本文学习如何使用jQuery获取和操作元素的属性和CSS样式. 元素属性和Dom属性 对于下面这样一个标签元素: <img id='img' src="1.jpg" alt= ...