先用BFS过滤出最短路中的路径,然后最小割最大流定理。
#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<vector>
#include<queue>
#define PII pair<int,int>
using namespace std;
const int maxn=1200;
struct Edge
{
int from,to,cap,flow,residual;//容量,流量,残量
};
struct node
{
int to;
int uw;
node(int t,int u)
{
to=t;
uw=u;
}
};
vector<node> DG[maxn];
vector< node > NG[maxn];//第一个表示来自哪,第二个表示这条边在fa里的编号
int dis[maxn];
vector<int> G[maxn];//这个存的是在边表里的位置
vector<Edge> E;
bool vis[maxn];
int d[maxn];
int cur[maxn];
int n,m;
void init()
{
for(int i=0;i<maxn;i++)
{
G[i].clear();
d[i]=0;
cur[i]=0;
dis[i]=0;
DG[i].clear();
NG[i].clear();
}
E.clear();
}
void Add_edge(int from,int to,int cap)
{
Edge tmp;
tmp.from=from;
tmp.to=to;
tmp.cap=cap;
tmp.flow=0;
tmp.residual=cap;
E.push_back(tmp);
tmp.from=to;
tmp.to=from;
tmp.cap=0;
tmp.flow=0;
tmp.residual=0;
E.push_back(tmp);
int m=E.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BFS(int S,int T)
{
memset(vis,0,sizeof(vis));
queue<int> Q;
Q.push(S);
d[S]=0;
//cout<<T<<endl;
vis[S]=1;
while(Q.empty()==false)
{
int x=Q.front();Q.pop();
for(int i=0;i<G[x].size();i++)
{
Edge &e=E[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];
}
int DFS(int x,int a,int T)
{
if(x==T || a==0) return a;
//cout<<a<<endl;
int flow=0;
int f;
for(int &i=cur[x];i<G[x].size();i++)
{
Edge &e=E[G[x][i]];
if(d[x]+1==d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow),T))>0)
{
e.flow+=f;
E[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
}
int Maxflow(int S,int T)
{
int flow=0;
while(BFS(S,T))
{
memset(cur,0,sizeof(cur));
flow+=DFS(S,0x3f3f3f3f,T);
//cout<<flow<<endl;
}
return flow;
}
bool MYBFS(int st,int tt)
{
memset(vis,0,sizeof(vis));
queue< pair< pair<int,int>,pair<int,int> > > Q;//目标节点,step,来自于哪里,以及他的编号
Q.push(make_pair(make_pair(st,0),make_pair(-1,0)));
while(Q.empty()==false)
{
int now=Q.front().first.first;
int step=Q.front().first.second;
PII zu=Q.front().second;
if(vis[now]==1)
{
if(dis[now]==step)
{
NG[zu.first].push_back(DG[zu.first][zu.second]);
}
Q.pop();
continue;
}
if(now!=st) NG[zu.first].push_back(DG[zu.first][zu.second]);
vis[now]=1;
dis[now]=step;
Q.pop();
int size=DG[now].size();
for(int i=0;i<size;i++)
{
int to=DG[now][i].to;
Q.push(make_pair(make_pair(to,step+1),make_pair(now,i)));
}
}
if(vis[tt]==0) return false;
else return true;
}
void copy_edge()
{
for(int i=1;i<=n;i++)
{
int size=NG[i].size();
for(int j=0;j<size;j++)
{
//printf("%d %d\n",i,NG[i][j]);
Add_edge(i,NG[i][j].to,NG[i][j].uw);
}
}
}
int main()
{
int TTT;cin>>TTT;
while(TTT--)
{
init();
cin>>n>>m;
for(int i=0;i<m;i++)
{
int a,b,uw;
scanf("%d %d %d",&a,&b,&uw);
DG[a].push_back(node(b,uw));
DG[b].push_back(node(a,uw));
}
bool judge=MYBFS(1,n);
if(judge==false)
{
printf("0\n");
continue;
}
copy_edge();
int ans=Maxflow(1,n);
printf("%d\n",ans);
}
return 0;
}