Road(bzoj 2750)

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

Sample Output

2

3

2

1

HINT

数据规模

30%的数据满足:n≤15、m≤30

60%的数据满足:n≤300、m≤1000

100%的数据满足:n≤1500、m≤5000、w≤10000

/*
        刚开始打的暴力,由于细节问题,挂成了10分,后来能改到50分。
        一种很容易想到的方法是DP,但是很无奈的是想不到一种更新方法能够保证拓扑序,然而Dijkstral可以记录图的拓扑序。
        记录每个节点前后各经过了几次,然后用乘法原理得到答案。
*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#define N 1510
#define M 5010
#define mod 1000000007
#define inf 1000000000
using namespace std;
int head[N],dis[N],inq[N],a[N],b[N],c[N],sum[M],n,m;
struct node{int v,w,pre;}e[M];
struct Node{
    int id,dist;
    bool operator< (const Node&s1) const {
        return s1.dist<dist;
    }
};priority_queue<Node> q;

void add(int i,int u,int v,int w){
    e[i].v=v;e[i].w=w;e[i].pre=head[u];head[u]=i;
}
void Dij(int S){
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(inq,0,sizeof(inq));
    for(int i=1;i<=n;i++) dis[i]=inf;int cnt=0;
    dis[S]=0;q.push((Node){S,0});
    while(!q.empty()){
        int x=q.top().id;q.pop();
        if(inq[x]) continue;
        inq[x]=1;c[++cnt]=x;
        for(int i=head[x];i;i=e[i].pre)
            if(dis[e[i].v]>dis[x]+e[i].w){
                dis[e[i].v]=dis[x]+e[i].w;
                q.push((Node){e[i].v,dis[e[i].v]});
            }
    }
    for(int i=1;i<=cnt;i++) b[c[i]]=1;
    a[S]=1;
    for(int i=1;i<=cnt;i++)
        for(int j=head[c[i]];j;j=e[j].pre)
            if(dis[c[i]]+e[j].w==dis[e[j].v]) a[e[j].v]+=a[c[i]],a[e[j].v]%=mod;
    for(int i=cnt;i;i--)
        for(int j=head[c[i]];j;j=e[j].pre)
            if(dis[c[i]]+e[j].w==dis[e[j].v]) b[c[i]]+=b[e[j].v],b[c[i]]%=mod;
    for(int i=1;i<=n;i++)
        for(int j=head[i];j;j=e[j].pre)
            if(dis[i]+e[j].w==dis[e[j].v]) sum[j]=(sum[j]+(long long)a[i]*b[e[j].v])%mod;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v,w;scanf("%d%d%d",&u,&v,&w);
        add(i,u,v,w);
    }
    for(int i=1;i<=n;i++) Dij(i);
    for(int i=1;i<=m;i++) printf("%d\n",sum[i]);
    return 0;
}
时间: 2024-10-02 11:32:42

Road(bzoj 2750)的相关文章

杭电 1596 find the safest road (最短路)

http://acm.hdu.edu.cn/showproblem.php?pid=1596 这道题目与杭电2544最短路的思想是一样的,只不过是把+改成了*,输入输出有些不一样而已. find the safest road Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6985    Accepted Submission(s)

SCOI2013 多项式的运算 (BZOJ 3323)

似乎仍然不能附传送门..权限题T_T... 3323: [Scoi2013]多项式的运算 Time Limit: 12 Sec  Memory Limit: 64 MB Description 某天,mzry1992 一边思考着一个项目问题一边在高速公路上骑着摩托车.一个光头踢了他一脚,摩托车损坏,而他也被送进校医院打吊针.现在该项目的截止日期将近,他不得不请你来帮助他完成这个项目.该项目的目的是维护一个动态的关于x 的无穷多项式F(x) = a0 * x^0 + a1 * x^1 + a2 *

分裂游戏(bzoj 1188)

Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子.标号为 i,j,k, 并要保证 i < j , j < = k 且第 i 个瓶子中至少要有 1 颗巧克力豆,随后这个人从第 i 个瓶子中拿走一颗豆 子并在 j,k 中各放入一粒豆子(j 可能等于 k) .如果轮到某人而他无法按规则取豆子,那么他将输 掉比赛.胜利者可以

食物(bzoj 3280)

Description 明明这次又要出去旅游了,和上次不同的是,他这次要去宇宙探险! 我们暂且不讨论他有多么NC,他又幻想了他应该带一些什么东西.理所当然的,你当然要帮他计算携带N件物品的方案数. 他这次又准备带一些受欢迎的食物,如:蜜桃多啦,鸡块啦,承德汉堡等等 当然,他又有一些稀奇古怪的限制: 每种食物的限制如下: 承德汉堡:偶数个 可乐:0个或1个 鸡腿:0个,1个或2个 蜜桃多:奇数个 鸡块:4的倍数个 包子:0个,1个,2个或3个 土豆片炒肉:不超过一个. 面包:3的倍数个 注意,这里

飞镖(bzoj 2335)

Description 飞镖是在欧洲颇为流行的一项运动.它的镖盘上分为20个扇形区域,分别标有1到20的分值,每个区域中有单倍.双倍和三倍的区域,打中对应的区域会得到分值乘以倍数所对应的分数.例如打中18分里面的三倍区域,就会得到54分.另外,在镖盘的中央,还有"小红心"和"大红心",分别是25分和50分. 通常的飞镖规则还有一条,那就是在最后一镖的时候,必须以双倍结束战斗,才算获胜.也就是说,当还剩12分的时候,必须打中双倍的6才算赢,而打中单倍的12或者三倍的4

外星千足虫(bzoj 1923)

Description Input 第一行是两个正整数 N, M. 接下来 M行,按顺序给出 Charles 这M次使用"点足机"的统计结果.每行 包含一个"01"串和一个数字,用一个空格隔开."01"串按位依次表示每只虫 子是否被放入机器:如果第 i 个字符是"0"则代表编号为 i 的虫子未被放入,"1" 则代表已被放入.后面跟的数字是统计的昆虫足数 mod 2 的结果. 由于 NASA的实验机器精确无误

BZOJ 2752:[HAOI2012]高速公路(road)(线段树)

[HAOI2012]高速公路(road) Description Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站.Y901高速公路是一条由N-1段路以及N个收费站组成的东西向的链,我们按照由西向东的顺序将收费站依次编号为1~N,从收费站i行驶到i+1(或从i+1行驶到i)需要收取Vi的费用.高速路刚建成时所有的路段都是免费的.政府部门根据实际情况,会不定期地对连续路段的收费标准进行调整,根据政策涨价或降价.无聊的

费用流(bzoj 3130)

Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识.    最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络流方案必须满足:(1)每条边的实际流量都不超过其最大流量且非负:(2)除了源点S和汇点T之外,对于其余所有点,都满足该点总流入流量等于该点总流出流量:而S点的净流出流量等于T点的净流入流量,这个值也即该网络流方案的总运输量.最大流问题就是对于给定的运输网络,求总运输量最大的网络流方案. 上图表示了一

hdu 1596 find the safest road (Dijksrta算法)

find the safest road Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7536    Accepted Submission(s): 2664 Problem Description XX星球有很多城市,每个城市之间有一条或多条飞行通道,但是并不是所有的路都是很安全的,每一条路有一个安全系数s,s是在 0 和 1