权值乘上一个大数M再+1,最后dinic得到的ans只需mod M 就是最小割情况下要割去的边数
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const __int64 inf=10000000000000LL;
const int maxn=100010;
int head[maxn],tol,dep[maxn],n;
struct node {
int from,to,next;
__int64 cap;
}edge[1000000];
void add(int u,int v,__int64 cap){
edge[tol]=(node){
u,v,head[u],cap
};
head[u]=tol++;
edge[tol]=(node){
v,u,head[v],0
};
head[v]=tol++;
}
int bfs(int s,int t){
int que[maxn],front=0,rear=0;
memset(dep,-1,sizeof(dep));
dep[s]=0;que[rear++]=s;
while(front!=rear){
int u=que[front++];front%=maxn;
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(edge[i].cap>0&&dep[v]==-1){
dep[v]=dep[u]+1;
que[rear++]=v;
rear%=maxn;
if(v==t)return 1;
}
}
}
return 0;
}
__int64 dinic(int s,int t){
__int64 res=0;
while(bfs(s,t)){
int Stack[maxn],top,cur[maxn];
memcpy(cur,head,sizeof(head));
top=0;
int u=s;
while(1){
if(t==u){
__int64 min=inf;
int loc;
for(int i=0;i<top;i++){
if(min>edge[Stack[i]].cap){
min=edge[Stack[i]].cap;
loc=i;
}
}
for(int i=0;i<top;i++){
edge[Stack[i]].cap-=min;
edge[Stack[i]^1].cap+=min;
}
res+=min;
top=loc;
u=edge[Stack[top]].from;
}
for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next)
if(dep[edge[i].to]==dep[u]+1&&edge[i].cap>0)break;
if(cur[u]!=-1){
Stack[top++]=cur[u];
u=edge[cur[u]].to;
}
else{
if(top==0)break;
dep[u]=-1;
u=edge[Stack[--top]].from;
}
}
}
return res;
}
int main(){
int i,j,m,T,t,s,p;
__int64 k;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
scanf("%d%d",&s,&t);
tol=0;
memset(head,-1,sizeof(head));
while(m--){
scanf("%d%d%I64d",&i,&j,&k);
add(i,j,k*200001+1);
}
__int64 ans=dinic(s,t);
printf("%I64d\n",ans%200001);
}
return 0;
}
2
4 5
1 4
1 2 3
1 3 1
2 3 1
2 4 1
3 4 2
4 5
1 4
1 2 3
1 3 1
2 3 1
2 4 1
3 4 3
输出
2
3