题目连接:https://cn.vjudge.net/problem/HDU-5889
题意就不说了,直接说思路,笨方法就是 先用SPFA 跑出最短路,把最短路建图,由于最小割,就是最大流,所以建好图之后直接dinic 求最大流
平常的最大流可能超时,我是用了边优化,才过的
#include <algorithm>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 20005;
int N,M;
int u,v,w;
struct Edge{
int to,value,rev;
Edge() {}
Edge(int a,int b,int c):to(a),value(b),rev(c) {}
};
struct node1{
int v,next,w;
}edge[MAXN];
vector<Edge> E[MAXN];
int deep[MAXN];
int iter[MAXN],head[MAXN];
int id;
void add(int u,int v,int w){
edge[id].v=v;
edge[id].w=w;
edge[id].next=head[u];
head[u]=id++;
}
inline void Add(int from,int to,int value){
E[from].push_back(Edge(to,value,E[to].size()));
E[to].push_back(Edge(from,0,E[from].size()-1));
}
bool BFS(int root,int target) {
memset(deep,-1,sizeof deep);
queue<int> Q;
deep[root] = 0;
Q.push(root);
while(!Q.empty())
{
int t = Q.front();
Q.pop();
for(int i=0 ; i<E[t].size() ; i++)
{
if(E[t][i].value > 0 && deep[E[t][i].to] == -1)
{
deep[E[t][i].to] = deep[t] + 1;
Q.push(E[t][i].to);
}
}
}
return deep[target] != -1;
}
int DFS(int root,int target,int flow){
if(root == target)return flow;
for(int &i=iter[root] ; i<E[root].size() ; i++)
{
if(E[root][i].value>0 && deep[E[root][i].to] == deep[root]+1)
{
int nowflow = DFS(E[root][i].to,target,min(flow,E[root][i].value));
if(nowflow > 0)
{
E[root][i].value -= nowflow;
E[E[root][i].to][E[root][i].rev].value += nowflow;
return nowflow;
}
}
}
return 0;
}
bool vis1[MAXN];
int cnt[MAXN];
bool vis[MAXN];
int dist[MAXN];
void spfa(int s){
memset(vis,0,sizeof(vis));
memset(dist,INF,sizeof(dist));
vis[s]=1;
dist[s]=0;
queue<int>q;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
if(u==N) break;
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if (dist[v]>dist[u]+1){
dist[v]=dist[u]+1;
if (!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
}
int Dinic(int root,int target){
int sumflow = 0;
while(BFS(root,target)) {
memset(iter,0,sizeof iter);
int mid;
while((mid=DFS(root,target,INF)) > 0)sumflow += mid;
}
return sumflow;
}
void init(){
for (int i = 0; i <= 2000;i++)head[i]=-1;
id=0;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d %d",&N,&M);
init();
for(int i=0 ; i< M ; i++){
scanf("%d %d %d",&u,&v,&w);
add(u, v,w);
add(v, u,w);
}
spfa(1);
for(int i = 1; i <= N; ++i) {
for(int j = head[i]; ~j; j = edge[j].next) {
int v = edge[j].v;
if(dist[v] - dist[i] == 1) {
Add(i, v, edge[j].w);
}
}
}
printf("%d\n",Dinic(1,N));
for (int i = 0; i <= 2000;i++) E[i].clear();
}
return 0;
}