最短路+最大流
#include<cstdio> #include<cstring> #include<string> #include<cmath> #include<vector> #include<queue> #include<algorithm> using namespace std; const int maxn=1000+10; const int MAXN=100000+10; const int INF=0x7FFFFFFF; struct Edge { int from,to,cap,flow; }; vector<Edge>edges; vector<int>G[maxn]; struct EE1 { int from,to,w; } ee1[MAXN]; struct EE2 { int from,to,w; } ee2[MAXN]; vector<EE1>SPFAG1[maxn]; vector<EE2>SPFAG2[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; int U[MAXN],V[MAXN],C[MAXN]; int FF1[maxn],Dis1[maxn],FF2[maxn],Dis2[maxn]; int n,m,s,t,N,M; //求出层次网络 bool BFS() { memset(vis,0,sizeof(vis)); queue<int>Q; Q.push(s); d[s]=0; vis[s]=1; while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0; i<G[x].size(); i++) { Edge& e=edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow) { vis[e.to]=1; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t]; } //加边 void AddEdge(int from,int to,int cap) { Edge r; r.from=from; r.to=to; r.cap=cap; r.flow=0; edges.push_back(r); Edge d; d.from=to; d.to=from; d.cap=0; d.flow=0; edges.push_back(d); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } //每个阶段来一次DFS增广 int DFS(int x,int a) { if(x==t||a==0) return a; int flow=0,f; for(int i=cur[x]; i<G[x].size(); i++) { Edge& e=edges[G[x][i]]; if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) { e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0) break; } } return flow; } //多个阶段,多次建立层次网络。 int Maxflow(int ss,int tt) { int flow=0; while(BFS()) { memset(cur,0,sizeof(cur)); flow+=DFS(ss,INF); } return flow; } void SPFA1() { for(int i=0; i<=N; i++) Dis1[i]=INF; queue<int>Q; Q.push(s); FF1[s]=1; Dis1[s]=0; while(!Q.empty()) { int h=Q.front(); Q.pop(); FF1[h]=0; for(int i=0; i<SPFAG1[h].size(); i++) { EE1 edge=SPFAG1[h][i]; if(Dis1[h]+edge.w<Dis1[edge.to]) { Dis1[edge.to]=Dis1[h]+edge.w; if(FF1[edge.to]==0) { FF1[edge.to]=1; Q.push(edge.to); } } } } } void SPFA2() { for(int i=0; i<=N; i++) Dis2[i]=INF; queue<int>Q; Q.push(t); FF2[t]=1; Dis2[t]=0; while(!Q.empty()) { int h=Q.front(); Q.pop(); FF2[h]=0; for(int i=0; i<SPFAG2[h].size(); i++) { EE2 edge=SPFAG2[h][i]; if(Dis2[h]+edge.w<Dis2[edge.to]) { Dis2[edge.to]=Dis2[h]+edge.w; if(FF2[edge.to]==0) { FF2[edge.to]=1; Q.push(edge.to); } } } } } int main() { int TT; scanf("%d",&TT); while(TT--) { scanf("%d%d",&N,&M); edges.clear(); for(int i=0; i<maxn; i++) G[i].clear(); for(int i=0; i<maxn; i++) SPFAG1[i].clear(); for(int i=0; i<maxn; i++) SPFAG2[i].clear(); for(int i=1; i<=M; i++) { scanf("%d%d%d",&U[i],&V[i],&C[i]); ee1[i].from=U[i]; ee1[i].to=V[i]; ee1[i].w=C[i]; ee2[i].from=V[i]; ee2[i].to=U[i]; ee2[i].w=C[i]; SPFAG1[U[i]].push_back(ee1[i]); SPFAG2[V[i]].push_back(ee2[i]); } scanf("%d%d",&s,&t); SPFA1();SPFA2(); for(int i=1; i<=M; i++) if(Dis1[U[i]]+Dis2[V[i]]+C[i]==Dis1[t]) AddEdge(U[i],V[i],1); printf("%d ",Maxflow(s,t)); } return 0; }