Marriage Match IV
Time limit:2000/1000 MS (java/others) Memory limit:32768/32768 K (java/others)
Total submission (s): 3368 Accepted Submission (s): 1001
Problem Descriptiondo not sincere non-interference.
Like the show, now Starvae also take part in a show, but it take place between City A and B. Starvae are in city A and GIR LS is in city B. Every time starvae can get to City B and make a data with a girl he likes. But there was problems with it, one was starvae must get to B within least time, it's said that he must take a shortest Path. Other are no road can be taken more than once. While the city starvae passed away can been taken more than once.
So, under a good RP, starvae May has many chances to get to City B. But he's don ' t know how many chances at most he can make a data with the girl he likes. Could help starvae?
Inputthe first line is a integer T indicating the case number. (1<=t<=65)
For each case,there is both integer n and m in the first line (2<=n<=1000, 0<=m<=100000), n is the number of The city and M are the number of the roads.
Then follows M line, each line has three integers a,b,c, (1<=a,b<=n,0<c<=1000) It means there is a road from a to B and it's distance are C, while there may has no road from B to a. There May has a road from a to a,but you can ignore it. If There is roads from a to B, they is different.
At last was a line with both integer A and B (1<=a,b<=n,a!=b), means the number of city A and city B.
There may is some blank line between the case.
Outputoutput a line with a integer, means the chances starvae can get on most.
Sample INPUT37 81 2 11 3 12 4 13 4 14 5 14 6 15 7 16 7 11 76 71 2 12 3 11 3 33 4 13 5 14 6 15 6 11 62 21 2 11 2 21 2
Sample Output211 Test Instructions: Given a map, there are n points, M-Edge, now a person want to go from point A to point B, every time to take the shortest way, but the most short circuit on each section of the road can only walk once, this time to go to the next time can not go here, ask a->b how many kinds of way to go? Puzzle: Suppose you and V is the shortest way point, then build a new picture, we are in the u-v with a capacity of 1 side is good, and then from A->b to do the maximum flow, but, how to judge U-v is the shortest way point? So we do a SPFA from point A, find the distance from point A to each point, and then reverse To build, from B Point also do the same operation, if DIS[A][U] + edge[u][v] + dis1[b][v] = dis[a][b], then u-v is the shortest way point. Side to open 200000, because the dinic algorithm to build the opposite edge, so open twice times.
#include <cstdio>#include<cstring>#include<queue>#include<algorithm>using namespacestd;Const intINF =999999999;Const intN =1005;Const intM =200005;structedge{intV,w,next;} EDGE[M];intHead[n];intLevel[n];inttot;voidinit () {memset (head,-1,sizeof(head)); Tot=0;}voidAddedge (intUintVintWint&k) {EDGE[K].V= v,edge[k].w=w,edge[k].next=head[u],head[u]=k++; EDGE[K].V= u,edge[k].w=0, edge[k].next=head[v],head[v]=k++;}intBFS (intSrcintdes) {Queue<int>Q; Memset (Level,0,sizeof(level)); LEVEL[SRC]=1; Q.push (SRC); while(!Q.empty ()) { intU =Q.front (); Q.pop (); if(U==des)return 1; for(intk = Head[u]; k!=-1; k=Edge[k].next) { intv =edge[k].v; intW =EDGE[K].W; if(level[v]==0&&w!=0) {Level[v]=level[u]+1; Q.push (v); } } } return-1;}intDfsintUintDesintincreaseroad) { if(u==des| | increaseroad==0) { returnIncreaseroad; } intret=0; for(intk=head[u];k!=-1; k=Edge[k].next) { intv = edge[k].v,w=EDGE[K].W; if(level[v]==level[u]+1&&w!=0){ intmin = min (increaseroad-ret,w); W=DFS (v,des,min); if(W >0) {EDGE[K].W-=W; Edge[k^1].w+=W; RET+=W; if(ret==increaseroad) { returnret; } } ElseLEVEL[V] =-1; if(increaseroad==0) Break; } } if(ret==0) level[u]=-1; returnret;}intDinic (intSrcintdes) { intAns =0; while(BFS (Src,des)!=-1) ans+=DFS (Src,des,inf); returnans;}structedge1{intV,w,next;} EDGE1[M],EDGE2[M];intHead1[n],head2[n];intTot1,tot2;intn,m,a,b;voidAddEdge1 (intUintVintWint&k) {EDGE1[K].V= V,edge1[k].w=w,edge1[k].next = head1[u],head1[u]=k++;}voidAddEdge2 (intUintVintWint&k) {EDGE2[K].V= V,edge2[k].w=w,edge2[k].next = head2[u],head2[u]=k++;}voidinit1 () {memset (Head1,-1,sizeof(HEAD1)); TOT1=0;}voidInit2 () {memset (head2,-1,sizeof(head2)); Tot2=0;}intlow[2][n];BOOLVis[n];voidSPFA (intSintTintFlagint*Head,edge1 edge[]) { for(intI=1; i<=n;i++) {Low[flag][i]=INF; Vis[i]=false; } Low[flag][s]=0; Queue<int>Q; Q.push (s); while(!Q.empty ()) { intU =Q.front (); Q.pop (); Vis[u]=false; for(intk=head[u];k!=-1; k=Edge[k].next) { intv = edge[k].v,w=EDGE[K].W; if(low[flag][v]>low[flag][u]+W) {Low[flag][v]= low[flag][u]+W; if(!Vis[v]) {Vis[v]=true; Q.push (v); } } } }}intMain () {inttcase; scanf ("%d",&tcase); while(tcase--) {init1 (); Init2 (); scanf ("%d%d",&n,&m); for(intI=1; i<=m;i++){ intu,v,w; scanf ("%d%d%d",&u,&v,&W); if(U==V)Continue; AddEdge1 (U,V,W,TOT1); AddEdge2 (V,U,W,TOT2); ///Reverse Edge} scanf ("%d%d",&a,&b); SPFA (A, B,0, Head1,edge1);///A->b First timeSPFA (B,a,1, Head2,edge2);///B->a Second timeinit (); for(intI=1; i<=n;i++){ for(intj=head1[i];j!=-1; j=Edge1[j].next) { intv = edge1[j].v,w=EDGE1[J].W; if(low[0][i]+low[1][v]+w==low[0][b]) {Addedge (i,v,1, tot); } } } if(low[0][b]==INF) {printf ("0\n"); Continue; } intMax_flow =Dinic (A, b); printf ("%d\n", Max_flow); } return 0;}
Hdu 3416 (Max Stream + shortest)