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

 

 

 

 

posted @ 2017-03-03 12:04  OldJang  阅读(487)  评论(0编辑  收藏  举报