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

    2750: [HAOI2012]Road

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 727  Solved: 348
    [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

    题解

       这题其实是前几天看见学弟在做就跟他口胡了一下……一看题目觉得好像很有意思然后看了下数据范围……随便搞啊……

       对于以每一个点作为起点s跑最短路并建出最短路图,然后在最短路图拓扑序上dp,用f1[i]表示从s到i有多少条路可走,然后f2[i]表示在这个最短路图上有多少从i出发的路径,就是把所有边方向反过来看有多少条路径可以到达i,然后对于每条在最短路上的边e[i],ans[i]+=f1[e[i].u]*f2[e[i].v],即从当前的s出发的最短路有多少条通过了e[i]

      1 /**************************************************************
      2     Problem: 2750
      3     User: 1090900715
      4     Language: Pascal
      5     Result: Accepted
      6     Time:1936 ms
      7     Memory:412 kb
      8 ****************************************************************/
      9  
     10 program j01;
     11 const mo=1000000007;
     12 var q,next,data,id:array[0..5006]of longint;
     13     bo:array[0..5006]of boolean;
     14     e:array[0..5006]of record u,v,w:longint; end;
     15     f1,f2:array[0..1506]of longint;
     16     head:array[0..1506]of longint;
     17     dis,l,rd:array[0..1506]of longint;
     18     inl:array[0..1506]of boolean;
     19     tp:array[0..1506]of longint;
     20     n,m,tt,h,tail,u,v,w,i:longint;
     21  
     22 procedure add(u,v,w,i:longint);
     23 begin
     24   inc(tt);q[tt]:=v;data[tt]:=w;next[tt]:=head[u];head[u]:=tt;id[i]:=tt;
     25 end;
     26  
     27 procedure spfa(s:longint);
     28 var i,j:longint;
     29 begin
     30   fillchar(dis,sizeof(dis),$3f);
     31   fillchar(inl,sizeof(inl),0);
     32   dis[s]:=0;inl[s]:=true;
     33   h:=0;tail:=1;l[1]:=s;
     34   while h<>tail do
     35   begin
     36     inc(h);if h>1500 then h:=1;
     37     i:=l[h];j:=head[i];
     38     while j>0 do
     39     begin
     40       if dis[i]+data[j]<dis[q[j]] then
     41       begin
     42         dis[q[j]]:=dis[i]+data[j];
     43         if inl[q[j]]=false then
     44         begin
     45           inc(tail);if tail>1500 then tail:=1;
     46           inl[q[j]]:=true;l[tail]:=q[j];
     47         end;
     48       end;
     49       j:=next[j];
     50     end;
     51     inl[i]:=false;
     52   end;
     53 end;
     54  
     55 procedure rebuild;
     56 var i,j:longint;
     57 begin
     58   fillchar(rd,sizeof(rd),0);
     59   fillchar(bo,sizeof(bo),0);
     60   for i:=1 to n do
     61   begin
     62     j:=head[i];
     63     while j>0 do
     64     begin
     65       if dis[i]+data[j]=dis[q[j]] then
     66       begin
     67         bo[j]:=true;inc(rd[q[j]]);
     68       end;
     69       j:=next[j];
     70     end;
     71   end;
     72 end;
     73  
     74 procedure tpsort(s:longint);
     75 var i,j:longint;
     76 begin
     77   h:=0;tail:=1;l[1]:=s;
     78   while h<tail do
     79   begin
     80     inc(h);i:=l[h];j:=head[i];
     81     while j>0 do
     82     begin
     83       if bo[j] then
     84       begin
     85         dec(rd[q[j]]);
     86         if rd[q[j]]=0 then
     87         begin
     88           inc(tail);l[tail]:=q[j];
     89         end;
     90       end;
     91       j:=next[j];
     92     end;
     93   end;
     94 end;
     95  
     96 procedure dp1(s:longint);
     97 var i,j,now:longint;
     98 begin
     99   fillchar(f1,sizeof(f1),0);
    100   f1[s]:=1;
    101   for i:=1 to tail do
    102   begin
    103     now:=l[i];j:=head[now];
    104     while j>0 do
    105     begin
    106       if bo[j] then f1[q[j]]:=(f1[q[j]]+f1[now])mod mo;
    107       j:=next[j];
    108     end;
    109   end;
    110 end;
    111  
    112 procedure dp2(s:longint);
    113 var i,j,tmp,now:longint;
    114 begin
    115   fillchar(f2,sizeof(f2),0);
    116   for i:=tail downto 1 do
    117   begin
    118     now:=l[i];j:=head[now];tmp:=0;
    119     f2[now]:=1;
    120     while j>0 do
    121     begin
    122       if bo[j] then
    123       begin
    124         f2[now]:=(f2[now]+f2[q[j]])mod mo;
    125         inc(tmp);
    126       end;
    127       j:=next[j];
    128     end;
    129   end;
    130 end;
    131  
    132 procedure solve(x:longint);
    133 var i:longint;
    134 begin
    135   spfa(x);
    136   rebuild;
    137   tpsort(x);
    138   dp1(x);
    139   dp2(x);
    140   for i:=1 to m do
    141     if bo[id[i]] then 
    142     e[i].w:=(e[i].w+(f1[e[i].u]*f2[e[i].v])mod mo)mod mo;
    143 end;
    144  
    145 begin
    146   readln(n,m);
    147   fillchar(head,sizeof(head),0);tt:=0;
    148   for i:=1 to m do
    149   begin
    150     readln(u,v,w);add(u,v,w,i);
    151     e[i].u:=u;e[i].v:=v;e[i].w:=0;
    152   end;
    153   for i:=1 to n do solve(i);
    154   for i:=1 to m do writeln(e[i].w);
    155 end.
    View Code
  • 相关阅读:
    递归 正则表达式 杨辉三角
    js 获取浏览器高度和宽度值
    CSS样式大全
    P2501 [HAOI2006]数字序列 (LIS,DP)(未完成)
    Luogu1064 金明的预算方案 (有依赖的背包)
    Luogu2783 有机化学之神偶尔会做作弊 (树链剖分,缩点)
    Luogu5020 货币系统 (完全背包)
    Luogu2798 爆弹虐场 (二分,Kruskal)
    luogu1419 寻找段落 (二分,单调队列)
    Luogu1083 借教室 (线段树)
  • 原文地址:https://www.cnblogs.com/oldjang/p/6495886.html
Copyright © 2011-2022 走看看