zoukankan      html  css  js  c++  java
  • [HAOI2012]Road


    C国有n座城市,城市之间通过m条单向道路连接。一条路径被称为最短路,当且仅当不存在从它的起点到终点的另
    外一条路径总长度比它小。两条最短路不同,当且仅当它们包含的道路序列不同。我们需要对每条道路的重要性进
    行评估,评估方式为计算有多少条不同的最短路经过该道路。现在,这个任务交给了你。
    Input
    第一行包含两个正整数n、m
    接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路
    n≤1500、m≤5000、w≤10000
    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

    Sol:针对每个点跑一次最短路,然后算出每条边的入度及出度。

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    #define ll long long
    #define sqr(x) ((x)*(x))
    #define lowbit(x) (x&(-x))
    #define mid ((l+r)>>1)
    #define ls now<<1,l,mid
    #define rs now<<1|1,mid+1,r
    using namespace std;
    const int N=5010,inf=1e9,p=1e9+7;
    inline int read()
    {
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
        return x*f;
    }
    int head[N],tot,dis[N],u,v,w,n,m,cnt,c[N];
    ll a[N],b[N],ans[N];
    struct fk
    {
        int to,nxt,w;
    }e[N];
    struct fq
    {
        int x,v;
        friend bool operator <(fq a,fq b){return a.v>b.v;}
    };
    bool in[N];
    void add(int u,int v,int w)
    {
    e[++cnt].to=v;
    e[cnt].nxt=head[u];
    e[cnt].w=w;
    head[u]=cnt;
    }
    void dijk(int s)
    {
        priority_queue<fq> q;
        memset(dis,63,sizeof(dis));
        memset(in,0,sizeof(in));
        q.push((fq){s,0});
    	dis[s]=0;tot=0;
        while(!q.empty())
    	{
            int x=q.top().x;
    		q.pop();
            if(in[x])continue;
            in[x]=1;
    		c[++tot]=x;
            for(int i=head[x];i;i=e[i].nxt)
                if(dis[e[i].to]>dis[x]+e[i].w)
                    dis[e[i].to]=dis[x]+e[i].w,q.push((fq){e[i].to,dis[e[i].to]}); 
        }
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        a[s]=1;
        for(int i=1;i<=tot;i++)
        	b[c[i]]=1;
        for(int i=1;i<=tot;i++)//取出最短路上的点 
            for(int j=head[c[i]];j;j=e[j].nxt) //j代表从c[i]这个点指出去的边 
                if(dis[c[i]]+e[j].w==dis[e[j].to])
    			   a[e[j].to]=(a[e[j].to]+a[c[i]])%p;//算出每个点的入度 
        for(int i=tot;i;i--)
            for(int j=head[c[i]];j;j=e[j].nxt)
                if(dis[c[i]]+e[j].w==dis[e[j].to])
    			b[c[i]]=(b[c[i]]+b[e[j].to])%p;//算出点的出度 
        for(int i=1;i<=n;i++)
            for(int j=head[i];j;j=e[j].nxt)
                if(dis[i]+e[j].w==dis[e[j].to])
    			ans[j]=(ans[j]+1LL*a[i]*b[e[j].to]%p)%p;
    }
    int main(){
        n=read();m=read();
        for(int i=1,u,v,w;i<=m;i++)
    	u=read(),v=read(),w=read(),add(u,v,w);
        for(int i=1;i<=n;i++)
         	dijk(i);
        for(int i=1;i<=m;i++)
    	printf("%lld\n",ans[i]);
    }
    

      

  • 相关阅读:
    springmvc
    POJ 3683 Priest John's Busiest Day
    POJ 3678 Katu Puzzle
    HDU 1815 Building roads
    CDOJ UESTC 1220 The Battle of Guandu
    HDU 3715 Go Deeper
    HDU 3622 Bomb Game
    POJ 3207 Ikki's Story IV
    POJ 3648 Wedding
    HDU 1814 Peaceful Commission
  • 原文地址:https://www.cnblogs.com/cutemush/p/11780217.html
Copyright © 2011-2022 走看看