Dinic模板找到残余网络 + 两个dfs找正流网络和负流网络
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 200;
const int maxe = 5000;
int visit[maxn], rvisit[maxn];
int head[maxn];//head应该为类中的私有成员,但是求最小割的时候要用,为了方便,我们把他提到外面
struct Edge {//Edge也应该为类中的私有成员
int from, to;
int next;
int cap;
} edge[maxe];
class Dinic {//我们把Dinic封装为一个类
public:
Dinic(int _s,int _t){
s=_s,t=_t;
cnt=0,res=0;
memset(head, -1, sizeof(head));
}
void addedge(int from, int to, int cap) {
edge[cnt].from = from, edge[cnt].to = to, edge[cnt].next = head[from];
edge[cnt].cap = cap, head[from] = cnt++;
edge[cnt].from = to, edge[cnt].to = from, edge[cnt].next = head[to];
edge[cnt].cap = 0, head[to] = cnt++;
}
int dinic() {
while (1) {
memset(dep, -1, sizeof(dep));
front = 0;
rear = 0;
que[rear++] = s;
dep[s] = 0;
while (front != rear) {
i = que[front++];
for (j = head[i]; j != -1; j = edge[j].next)
if (edge[j].cap && dep[edge[j].to] == -1) {
dep[edge[j].to] = dep[i] + 1;
que[rear++] = edge[j].to;
}
}
if (dep[t] == -1)
break;
memcpy(cur, head, sizeof(head));
for (i = s, top = 0;;) {
if (i == t) {
min = INF;
for (k = 0; k < top; k++)
if (min > edge[que[k]].cap) {
min = edge[que[k]].cap;
front = k;
}
for (k = 0; k < top; k++) {
edge[que[k]].cap -= min;
edge[que[k] ^ 1].cap += min;
}
res += min;
i = edge[que[top = front]].from;
}
for (j = cur[i]; cur[i] != -1; j = cur[i] = edge[cur[i]].next)
if (dep[edge[j].to] == dep[i] + 1 && edge[j].cap)
break;
if (cur[i] != -1) {
que[top++] = cur[i];
i = edge[cur[i]].to;
} else {
if (top == 0)
break;
dep[i] = -1;
i = edge[que[--top]].from;
}
}
}
return res;
}
public:
int cnt,dep[maxn], que[maxn], cur[maxn];
int i, j, k, front, rear, top, min, res,s,t;
};
void dfs(int u) {
visit[u] = 1;
for (int i = head[u]; i != -1; i = edge[i].next) {
int to = edge[i].to;
if (visit[to] == 0 && edge[i].cap)
dfs(to);
}
}
void rdfs(int u) {
rvisit[u] = 1;
for (int i = head[u]; i != -1; i = edge[i].next) {
int to = edge[i].to;
if (edge[i ^ 1].cap && rvisit[to] == 0)
rdfs(to);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("E:\\input.txt", "r", stdin);
#endif // ONLINE_JUDGE
int n, m, l,i, x, y,c;
int ans[maxe];
while (~scanf("%d%d%d", &n, &m, &l)&&n+m+l) {
Dinic DC(n+m+1,0);
for (i = 0; i < l; i++) {
scanf("%d%d%d", &x, &y, &c);
DC.addedge(x, y, c);
}
for (i = 1; i <= n; i++)
DC.addedge(n + m + 1, i, INF);
DC.dinic();
memset(visit, 0, sizeof(visit));
memset(rvisit, 0, sizeof(rvisit));
dfs(n + m + 1),rdfs(0);
int k = 0;
for (i = 0; i < DC.cnt; i += 2) {
x = edge[i].from;
y = edge[i].to;
if (visit[x] == 1 && rvisit[y] == 1 && edge[i].cap == 0)
ans[k++] = i / 2 + 1;
}
if (k == 0)
printf("\n");
else {
printf("%d", ans[0]);
for (i = 1; i < k; i++)
printf(" %d", ans[i]);
printf("\n");
}
}
return 0;
}