http://acm.hdu.edu.cn/showproblem.php?pid=6214
题意:
最小割边的模版
思路:
建边的时候权值w= w * ( E + 1) + 1
得到的最大流为 maxflow/(E + 1), 最小割边为maxflow%(E+1)
#include <iostream>
#include <string.h>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <stdio.h>
#include <deque>
using namespace std;
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define maxn 100005
#define eps 0.00000001
#define PI acos(-1.0)
#define M 1000000007
struct Edge{
int v, w, nxt;
}edge[maxn];
int head[maxn], gap[maxn], dis[maxn], Cur[maxn], maxflow, aug, isFind, tot;
int Case, n , m, st, en;
void init() {
tot = 0;
memset(head, -1, sizeof(head));
}
void addEdge(int u, int v, int w) {
edge[tot].v = v;
edge[tot].w = w;
edge[tot].nxt = head[u];
head[u] = tot ++;
edge[tot].v = u;
edge[tot].w = 0;
edge[tot].nxt = head[v];
head[v] = tot ++;
}
bool bfs() {
memset(dis, -1, sizeof(dis));
memset(gap, 0, sizeof(gap));
dis[en] = 0;
gap[0] = 1;
queue<int> que;
que.push(en);
while(!que.empty()) {
int u = que.front(); que.pop();
for (int i = head[u]; i + 1; i = edge[i].nxt) {
if(dis[edge[i].v] == -1 && edge[i ^ 1].w > 0) {
dis[edge[i].v] = dis[u] + 1;
gap[dis[edge[i].v]] ++;
que.push(edge[i].v);
}
}
}
return dis[st] != -1;
}
/*void SAP(int u) {
if(u == en) {
maxflow += aug;
isFind = 1;
return ;
}
int dx, augc, minDis;
augc = aug;
minDis = n - 1;
for (int i = head[u]; i + 1; i = edge[i].nxt) {
int v = edge[i].v;
if(edge[i].w > 0) {
if(dis[u] == dis[edge[i].v] + 1) {
aug = min(aug, edge[i].w);
SAP(edge[i].v);
if(dis[st] >= n) return ;
if(isFind) {
dx = i;
break;
}
aug = augc;
}
minDis = min(minDis, dis[edge[i].w]);
}
}
if(!isFind) {
gap[dis[u]] --;
if(gap[dis[u]] == 0) dis[st] = n;
dis[u] = minDis + 1;
gap[dis[u]] ++;
}else {
edge[dx].w -= aug;
edge[dx ^ 1].w += aug;
}
}
*/
int dfs(int u, int flow) {
if(u == en) return flow;
int delte = flow;
for (int &i = Cur[u]; i + 1; i = edge[i].nxt) {
if(dis[u] == dis[edge[i].v] + 1 && edge[i].w > 0) {
int d = dfs(edge[i].v, min(delte, edge[i].w));
edge[i].w -= d; edge[i ^ 1].w += d;
delte -= d;
if(delte == 0) break;
}
}
return flow - delte;
}
int dinic() {
int ans = 0;
while(bfs()) {
for (int i = 0; i <= n; i ++)
Cur[i] = head[i];
ans += dfs(st, INF);
}
return ans;
}
int main(int argc, const char * argv[]) {
scanf("%d", &Case);
while(Case --) {
init();
scanf("%d %d", &n, &m);
scanf("%d %d", &st, &en);
for (int i = 0; i < m; i ++) {
int u, v, w;
scanf("%d%d %d", &u, &v, &w);
addEdge(u, v, w * 1000 + 1);
}
printf("%d\n", dinic() % 1000);
}
return 0;
}