首先,最短路不同的两辆车一定不会发生堵塞

对于最短路相同的点,我们把属于最短路径上的边拎出来建图跑最大流即可

然后我TLE了……

因为很明显建出来图很大,而真正流的流量很小

普通的初始标号都是0的sap在增广的时候编号会非常慢

运用fanhq博客里的做法,先用dfs计算图的标号O(m+n),然后再跑sap就跑得飞起了

  1 const inf=1000000007;
  2 type node=record
  3        po,next,flow:longint;
  4      end;
  5      point=record
  6        loc,num:longint;
  7      end;
  8      way=record
  9        po,next,num:longint;
 10      end;
 11 
 12 var w:array[0..100010] of way;
 13     e:array[0..400010] of node;
 14     h:array[0..25010] of point;
 15     v:array[0..25010] of boolean;
 16     wh,d,a,cur,hi,pre,p,q,numh:array[0..25010] of longint;
 17     ans,j,i,len,n,m,t,c,x,y,z:longint;
 18 
 19 procedure swap(var a,b:point);
 20   var c:point;
 21   begin
 22     c:=a;
 23     a:=b;
 24     b:=c;
 25   end;
 26 
 27 procedure sift(i:longint);
 28   var j,x,y:longint;
 29   begin
 30     j:=i shl 1;
 31     while j<=t do
 32     begin
 33       if (j<t) and (h[j].num>h[j+1].num) then inc(j);
 34       if h[i].num>h[j].num then
 35       begin
 36         x:=h[i].loc;
 37         y:=h[j].loc;
 38         wh[x]:=j;
 39         wh[y]:=i;
 40         swap(h[i],h[j]);
 41         i:=j;
 42         j:=j shl 1;
 43       end
 44       else break;
 45     end;
 46   end;
 47 
 48 procedure up(i:longint);
 49   var j,x,y:longint;
 50   begin
 51     j:=i shr 1;
 52     while j>0 do
 53     begin
 54       if h[i].num<h[j].num then
 55       begin
 56         x:=h[i].loc;
 57         y:=h[j].loc;
 58         wh[x]:=j;
 59         wh[y]:=i;
 60         swap(h[i],h[j]);
 61         i:=j;
 62         j:=j shr 1;
 63       end
 64       else break;
 65     end;
 66   end;
 67 
 68 procedure dij;
 69   var i,k,x,y:longint;
 70   begin
 71     t:=n;
 72     for i:=1 to n do
 73     begin
 74       if i=1 then d[i]:=0 else d[i]:=inf;
 75       wh[i]:=i;
 76       h[i].num:=d[i];
 77       h[i].loc:=i;
 78     end;
 79     for k:=1 to n-1 do
 80     begin
 81       x:=h[1].loc;
 82       wh[h[t].loc]:=1;
 83       swap(h[1],h[t]);
 84       dec(t);
 85       sift(1);
 86       i:=q[x];
 87       while i<>0 do
 88       begin
 89         y:=w[i].po;
 90         if d[x]+w[i].num<d[y] then
 91         begin
 92           d[y]:=d[x]+w[i].num;
 93           h[wh[y]].num:=d[y];
 94           up(wh[y]);
 95         end;
 96         i:=w[i].next;
 97       end;
 98     end;
 99   end;
100 
101 function cmp(i,j:longint):boolean;
102   begin
103     if d[i]=d[j] then exit(i<j);
104     exit(d[i]<d[j]);
105   end;
106 
107 procedure sort(l,r:longint);
108   var i,j,x,y:longint;
109   begin
110     i:=l;
111     j:=r;
112     x:=a[(l+r) shr 1];
113     repeat
114       while cmp(a[i],x) do inc(i);
115       while cmp(x,a[j]) do dec(j);
116       if not(i>j) then
117       begin
118         y:=a[i]; a[i]:=a[j]; a[j]:=y;
119         inc(i);
120         dec(j);
121       end;
122     until i>j;
123     if l<j then sort(l,j);
124     if i<r then sort(i,r)
125   end;
126 
127 procedure add(x,y,f:longint);
128   begin
129     inc(len);
130     e[len].po:=y;
131     e[len].flow:=f;
132     e[len].next:=p[x];
133     p[x]:=len;
134   end;
135 
136 procedure build(x,y,f:longint);
137   begin
138     add(x,y,f);
139     add(y,x,0);
140   end;
141 
142 procedure ins(x,y,z:longint);
143   begin
144     inc(len);
145     w[len].po:=y;
146     w[len].num:=z;
147     w[len].next:=q[x];
148     q[x]:=len;
149   end;
150 
151 function sap(lim:longint):longint;
152   var i,j,u,tmp,q:longint;
153   begin
154     u:=0; sap:=0;
155     while hi[0]<n+1 do
156     begin
157       i:=cur[u];
158       while i<>-1 do
159       begin
160         j:=e[i].po;
161         if (e[i].flow>0) and (hi[u]=hi[j]+1) then
162         begin
163           pre[j]:=u;
164           cur[u]:=i;
165           u:=j;
166           if u=1 then
167           begin
168             inc(sap);
169             if sap=lim then exit;
170             while u<>0 do
171             begin
172               u:=pre[u];
173               j:=cur[u];
174               dec(e[j].flow);
175               inc(e[j xor 1].flow);
176             end;
177           end;
178           break;
179         end;
180         i:=e[i].next;
181       end;
182       if i=-1 then
183       begin
184         dec(numh[hi[u]]);
185         if numh[hi[u]]=0 then break;
186         tmp:=n;
187         q:=-1;
188         i:=p[u];
189         while i<>-1 do
190         begin
191           j:=e[i].po;
192           if e[i].flow>0 then
193             if hi[j]<tmp then
194             begin
195               q:=i;
196               tmp:=hi[j];
197             end;
198           i:=e[i].next;
199         end;
200         cur[u]:=q;
201         hi[u]:=tmp+1;
202         inc(numh[hi[u]]);
203         if u<>0 then u:=pre[u];
204       end;
205     end;
206   end;
207 
208 procedure dfs(x:longint);
209   var tmp,i,y,q:longint;
210   begin
211     if x=1 then
212     begin
213       hi[1]:=0;
214       inc(numh[0]);
215       exit;
216     end;
217     v[x]:=true;
218     tmp:=n;
219     q:=-1;
220     i:=p[x];
221     while i<>-1 do
222     begin
223       y:=e[i].po;
224       if e[i].flow>0 then
225       begin
226         if not v[y] then dfs(y);
227         if hi[y]<tmp then
228         begin
229           tmp:=hi[y];
230           q:=i;
231         end;
232       end;
233       i:=e[i].next;
234     end;
235     cur[x]:=q;
236     hi[x]:=tmp+1;
237     inc(numh[hi[x]]);
238   end;
239 
240 procedure work(l,r:longint);
241   var i,j:longint;
242   begin
243     len:=-1;
244     fillchar(p,sizeof(p),255);
245     for i:=1 to n do
246     begin
247       j:=q[i];
248       while j<>0 do
249       begin
250         y:=w[j].po;
251         if d[i]+w[j].num=d[y] then build(y,i,1);
252         j:=w[j].next;
253       end;
254     end;
255     i:=l;
256     while i<=r do
257     begin
258       j:=i+1;
259       while (j<=r) and (a[j]=a[i]) do inc(j);
260       build(0,a[i],j-i);
261       i:=j;
262     end;
263     fillchar(numh,sizeof(numh),0);
264     fillchar(v,sizeof(v),false);
265     dfs(0);
266     if hi[0]<n+1 then
267       ans:=ans+sap(r-l+1);
268   end;
269 
270 begin
271   readln(n,m,c);
272   for i:=1 to m do
273   begin
274     readln(x,y,z);
275     ins(x,y,z);
276     ins(y,x,z);
277   end;
278   dij;
279   for i:=1 to c do
280     read(a[i]);
281   sort(1,c);
282   i:=1;
283   while i<=c do
284   begin
285     j:=i+1;
286     while (d[a[i]]=d[a[j]]) and (j<=c) do inc(j);
287     if j=i+1 then inc(ans)
288     else if a[i]=1 then inc(ans,j-i)
289     else work(i,j-1);
290     i:=j;
291   end;
292   writeln(ans);
293 end.
View Code

 

posted on 2015-06-30 10:25  acphile  阅读(283)  评论(0编辑  收藏  举报