题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=565&page=show_problem&problem=2205
题意:见大白书368页
要注意的地方在大白书上面也都说了,不过做的时候被求割点卡了。。之前没做过- -。长了见识。
求割的那部分是这样的:因为最后已经走不过去了,所以如果某条边起点能走到,终点走不到,那说明它就是在最小割的集合里面,否则就还有增广路。
/*
* ThinkingLion.cpp
*
* Created on: 2014年11月25日
* Author: dell
*/
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfs(a) printf("%s\n",a)
#define pfI(a) printf("%I64d\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define clr1(a) memset(a,0,sizeof(a))
#define clr2(a) memset(a,-1,sizeof(a))
#define ll __int64
const double PI = acos(-1.0);
template<class T> T gcd(T a, T b) {
return b ? gcd(b, a % b) : a;
}
template<class T> T lcm(T a, T b) {
return a / gcd(a, b) * b;
}
template<class T> inline T Min(T a, T b) {
return a < b ? a : b;
}
template<class T> inline T Max(T a, T b) {
return a > b ? a : b;
}
using namespace std;
int n, e, c;
#define N 110
struct Edge {
int from, to, cap, flow;
};
struct Dinic {
int n, m, s, t;
vector<Edge> edges;
vector<Edge> edtmp;
vector<int> G[N];
vector<int> cut;
Edge able[N * N * 2];
int p[N];
bool vis[N];
int d[N];
int cur[N];
int k;
int flow;
void Init(int n, int m, int s, int t) {
this->n = n;
this->m = m;
this->s = s;
this->t = t;
for (int i = 0; i <= N; i++)
G[i].clear();
edges.clear();
flow = 0;
}
void addEdge(int u, int v, int cap) {
edges.push_back((Edge ) { u, v, cap, 0 });
edges.push_back((Edge ) { v, u, 0, 0 });
m = edges.size();
G[u].push_back(m - 2);
G[v].push_back(m - 1);
}
bool BFS() {
memset(vis, 0, sizeof vis);
queue<int> q;
q.push(s);
vis[s] = 1;
d[s] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = 0; i < (int) G[u].size(); i++) {
Edge &e = edges[G[u][i]];
if (e.cap > e.flow && !vis[e.to]) {
vis[e.to] = 1;
d[e.to] = d[u] + 1;
q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x, int a) {
if (x == t || a == 0)
return a;
int flow = 0, f;
for (int &i = cur[x]; i < (int) G[x].size(); i++) {
Edge &e = edges[G[x][i]];
if (d[x] + 1 == d[e.to]
&& (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
e.flow += f;
edges[G[x][i] ^ 1].flow -= f;
flow += f;
a -= f;
if (a == 0)
break;
}
}
return flow;
}
int maxFlow() {
while (BFS()) {
memset(cur, 0, sizeof cur);
flow += DFS(s, INF);
if (flow >= c)
return true;
}
return false;
}
void getcut() {
BFS();
cut.clear();
for (int i = 0; i < (int) edges.size(); i += 2) {
if (vis[edges[i].from] && !vis[edges[i].to] && edges[i].cap > 0) {
cut.push_back(i);
}
}
}
void getTable() {
getcut();
edtmp.clear();
for (int i = 0; i < (int) edges.size(); i++)
edtmp.push_back(edges[i]);
int lastflow = flow;
k = 0;
for (int i = 0; i < (int) cut.size(); i++) {
edges[cut[i]].cap = edges[cut[i]].flow + c;
if (maxFlow())
able[k++] = edges[cut[i]];
flow = lastflow;
edges.clear();
for (int j = 0; j < (int) edtmp.size(); j++)
edges.push_back(edtmp[j]);
}
}
};
Dinic solver;
bool cmp(Edge a, Edge b) {
if (a.from < b.from)
return true;
else if (a.from == b.from && a.to < b.to)
return true;
return false;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
int kas = 1;
while (scanf("%d%d%d", &n, &e, &c) != EOF && n + e + c) {
solver.Init(n, e, 1, n);
int u, v, cap;
for (int i = 0; i < e; i++) {
scanf("%d%d%d", &u, &v, &cap);
solver.addEdge(u, v, cap);
}
printf("Case %d: ", kas++);
if (solver.maxFlow() || c == 0)
printf("possible\n");
else {
solver.getTable();
if (solver.k <= 0)
printf("not possible\n");
else {
sort(solver.able, solver.able + solver.k, cmp);
printf("possible option:(%d,%d)", solver.able[0].from,
solver.able[0].to);
for (int i = 1; i < solver.k; i++) {
printf(",(%d,%d)", solver.able[i].from, solver.able[i].to);
}
printf("\n");
}
}
}
return 0;
}