题解: 题目要求最大流达到c,达不到的话,就找一条边加容量。
先走一遍dinic()如果最大流不够,就在容量已经降为0的边上尝试加容量,重新走Dinic即可。
需要注意的是在找边的时候,遍历的步长为2,否则会把添加的虚拟反向边给考虑进去
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
using namespace std;
const int maxn = 110;
const int maxm = 20010;
const int INF = 2e10;
int n,m;
int c;
struct Edge {
int to, cap, next;
} e[maxm], cur[maxm];
int tot;
int head[maxn];
bool used[maxn];
int depth[maxn];
void addEdge(int u,int v,int c) {
e[tot] = (Edge){v,c,head[u]};
head[u] = tot++;
e[tot] = (Edge){u,0,head[v]};
head[v] = tot++;
}
bool BFS() {
memset(used, 0, sizeof(used));
memset(depth, -1, sizeof(depth));
depth[1] = 0;
used[1] = true;
queue<int> q;
q.push(1);
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = head[u]; i!=-1; i = e[i].next) {
int v = e[i].to;
if(e[i].cap == 0) continue;
if(used[v]) continue;
depth[v] = depth[u] + 1;
used[v] = true;
q.push(v);
}
}
return depth[n] != -1;
}
int Dinic(int u, int maxflow) {
if(u == n) {
return maxflow;
}
int t = 0;
for(int i = head[u]; i!=-1; i = e[i].next) {
int v = e[i].to;
if(e[i].cap == 0) continue;
if(t >= maxflow) continue;
if(depth[v] != depth[u] + 1) continue;
int f = Dinic(v, min(maxflow-t, e[i].cap));
e[i].cap -= f;
e[i^1].cap += f;
t += f;
}
if(!t) depth[u] = -1; // ?
return t;
}
int main() {
// freopen("out.txt","w",stdout);
int kase = 1;
while(scanf("%d%d%d",&n,&m,&c) != EOF) {
memset(head, -1, sizeof(head));
tot = 0;
if(n==0&&m==0&&c==0) break;
printf("Case %d: ", kase++);
for(int i = 0;i < m;i++) {
int u,v,c;
scanf("%d%d%d", &u,&v,&c);
addEdge(u,v,c);
}
int MaxFlow = 0;
// Dinic
while(BFS()) {
// memset(pre, -1, sizeof(pre));
MaxFlow += Dinic(1, INF);
}
if(MaxFlow >= c) {
printf("possible\n");
continue;
}
vector<pair<int, int> > vec;
int residual = c - MaxFlow;
for(int i = 0;i < tot;i+=2) {
if(e[i].cap != 0) continue;
int v = e[i].to;
int u = e[i^1].to;
memcpy(cur, e, sizeof(e));
e[i].cap += residual;
int MaxFlow = 0;
// Dinic
while(BFS()) {
// memset(pre, -1, sizeof(pre));
MaxFlow += Dinic(1, INF);
}
if(MaxFlow >= residual) vec.push_back(make_pair(u, v));
memcpy(e, cur, sizeof(cur));
}
int len = vec.size();
if(len == 0) {
printf("not possible\n");
continue;
}
sort(vec.begin(), vec.end());
printf("possible option:");
for(int i = 0;i < len;i++) {
printf("(%d,%d)",vec[i].first, vec[i].second);
if(i != len-1) {
printf(",");
}
}
printf("\n");
}
return 0;
}