题意:
给你一个有向图,求最小割的最小割边数。
思路:
上网搜到两种方法,其中一种是错的,因为最小割的割边一定为满流,但满流的边不一定是最小割的割边。
还有,用ford-fulkerson算法会超时,,所以得用更快的dinic算法
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 210;
const int inf = 0x3f3f3f3f;
struct edge
{
int to,cap,rev;
};
vector<edge> g[maxn];
int n,m,level[maxn];
void add(int from,int to,int cap)
{
g[from].push_back((edge){to,cap,g[to].size()});
g[to].push_back((edge){from,0,g[from].size()-1});
}
int bfs(int s,int t)
{
memset(level,-1,sizeof(level));
queue<int> q;
q.push(s);
level[s] = 0;
while(!q.empty())
{
int u = q.front();
q.pop();
if(u==t)
return 1;
for(int i = 0;i<g[u].size();i++)
{
edge &e = g[u][i];
if(level[e.to]<0&&e.cap>0)
{
level[e.to] = level[u]+1;
q.push(e.to);
}
}
}
return 0;
}
int dfs(int u,int t,int f)
{
if(u==t)
return f;
for(int i = 0;i<g[u].size();i++)
{
edge &e = g[u][i];
if(e.cap>0&&level[u]+1==level[e.to])
{
int d = dfs(e.to,t,min(e.cap,f));
if(d>0)
{
e.cap -= d;
g[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
int dinic(int s,int t)
{
int ans = 0;
while(bfs(s,t))
{
ans += dfs(s,t,inf);
}
return ans;
}
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;i++)
g[i].clear();
int s,t;
scanf("%d%d",&s,&t);
for(int i = 0;i<m;i++)
{
int u,v,val;
scanf("%d%d%d",&u,&v,&val);
add(u,v,val*(m+1)+1);
}
printf("%d\n",dinic(s,t)%(m+1));
}
return 0;
}