zoukankan      html  css  js  c++  java
  • 【BZOJ】【2750】【HAOI2012】Road

    最短路+拓扑序DP


      orz zyf & lyd

      统计每条边在多少条最短路径上……其实可以统计 有多少条最短路径经过了x,以及y出发到达任意一个结束点有多少种走法(沿最短路)

      我们可以用Dijkstra求出以 i 为起点的最短路径图,它是一个DAG,然后我们用dij扩展的顺序(一个拓扑序)来搞DP!

        令a[x]表示从 i 沿最短路走到 x 的方案数,b[x]表示从 x 往出走,沿最短路走到任意一个结束结点的总方案(就是经过x的最短路条数?只不过只看后半段)

      其实就是将最短路分开两半进行统计了……然后乘一下……

      通过这题的思路可以搞CTSC2015 Day1 T1?

      跪了,pq应该把<定义为a.d>b.d……唉真是傻逼了

     1 /**************************************************************
     2     Problem: 2750
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:2276 ms
     7     Memory:1388 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 2750
    11 #include<queue>
    12 #include<vector>
    13 #include<cstdio>
    14 #include<cstring>
    15 #include<cstdlib>
    16 #include<iostream>
    17 #include<algorithm>
    18 #define rep(i,n) for(int i=0;i<n;++i)
    19 #define F(i,j,n) for(int i=j;i<=n;++i)
    20 #define D(i,j,n) for(int i=j;i>=n;--i)
    21 #define pb push_back
    22 using namespace std;
    23 inline int getint(){
    24     int v=0,sign=1; char ch=getchar();
    25     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    26     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    27     return v*sign;
    28 }
    29 const int N=1510,M=5010,INF=~0u>>2;
    30 const int P=1000000007;
    31 typedef long long LL;
    32 /******************tamplate*********************/
    33 int to[M],next[M],len[M],head[N],cnt;
    34 void add(int x,int y,int z){
    35     to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt; len[cnt]=z;
    36 }
    37 struct node{
    38     int x,d;
    39     bool operator < (const node &b)const{ return d>b.d;}
    40 };
    41 int n,m,v[N],a[N],b[N],c[N],d[N];
    42 priority_queue<node>Q;
    43 int ans[M];
    44 void dijkstra(int S){
    45     memset(d,0x3f,sizeof d);
    46     memset(v,0,sizeof v);
    47     d[S]=0;
    48     int t=0;
    49     Q.push((node){S,0});
    50     while(!Q.empty()){
    51         int x=Q.top().x; Q.pop();
    52         if (v[x]) continue;
    53         v[x]=++t;
    54         for(int i=head[x];i;i=next[i]){
    55             int y=to[i],l=len[i];
    56             if (d[y]>d[x]+l){
    57                 d[y]=d[x]+l;
    58                 Q.push((node){y,d[y]});
    59             }
    60         }
    61     }
    62     F(i,1,n) if (v[i]) c[v[i]]=i;
    63     memset(a,0,sizeof a); a[c[1]]=1;
    64     F(i,1,n) b[i]=1;
    65     F(x,1,t)
    66         for(int i=head[c[x]];i;i=next[i])
    67             if (d[to[i]]==d[c[x]]+len[i]) 
    68                 a[to[i]]=(a[to[i]]+a[c[x]])%P;
    69     D(x,t,1)
    70         for(int i=head[c[x]];i;i=next[i])
    71             if (d[to[i]]==d[c[x]]+len[i]) 
    72                 b[c[x]]=(b[c[x]]+b[to[i]])%P;
    73     F(x,1,n)
    74         for(int i=head[x];i;i=next[i])
    75             if (d[to[i]]==d[x]+len[i])
    76                 ans[i]=(ans[i]+(LL)a[x]*b[to[i]]%P)%P;
    77 }
    78 int main(){
    79 #ifndef ONLINE_JUDGE
    80     freopen("2750.in","r",stdin);
    81     freopen("2750.out","w",stdout);
    82 #endif
    83     n=getint(); m=getint();
    84     F(i,1,m){
    85         int x=getint(),y=getint(),z=getint();
    86         add(x,y,z);
    87     }
    88     F(i,1,n) dijkstra(i);
    89     F(i,1,m) printf("%d
    ",ans[i]);
    90     return 0;
    91 }
    View Code

    2750: [HAOI2012]Road

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 347  Solved: 155
    [Submit][Status][Discuss]

    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

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    LINUX内核分析第三周学习总结——构造一个简单的Linux系统MenuOS
    Linux第二周学习总结——操作系统是如何工作的
    通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
    期末总结
    实验报告(实验五)
    HTTPServletResponse
    Eclipse 枚举类报错
    出现Unreachable code问题的原因
    myeclipse自动保存修改代码
    ssh连接虚拟机失败解决办法
  • 原文地址:https://www.cnblogs.com/Tunix/p/4480551.html
Copyright © 2011-2022 走看看