bzoj2750: [HAOI2012]Road
2750: [HAOI2012]Road
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 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
1 2 5
2 3 5
3 4 5
1 4 8
Sample Output
2
3
2
1
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.