Dinic
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<set> 7 #include<map> 8 #include<vector> 9 #include<cstring> 10 #include<stack> 11 #include<cmath> 12 #include<queue> 13 using namespace std; 14 #define INF 0x3f3f3f3f 15 #define LL long long 16 #define MAXN 110 17 struct Edge{ 18 int from, to, cap, flow; 19 }; 20 bool comp(const Edge& a, const Edge& b){ 21 return a.from < b.from || (a.from == b.from && a.to < b.to); 22 } 23 struct Dinic{ 24 int n, m, s, t; 25 vector<Edge> edges; 26 vector<int> G[MAXN]; 27 bool vis[MAXN]; 28 int d[MAXN]; 29 int cur[MAXN]; 30 void init(int n){ 31 this->n = n; 32 for (int i = 0; i <= n; i++) 33 G[i].clear(); 34 edges.clear(); 35 } 36 void AddEdge(int from, int to, int cap){ 37 edges.push_back(Edge{ from, to, cap, 0 }); 38 edges.push_back(Edge{ to, from, 0, 0 }); 39 m = edges.size(); 40 G[from].push_back(m - 2); 41 G[to].push_back(m - 1); 42 } 43 bool BFS(){ 44 memset(vis, 0, sizeof(vis)); 45 queue<int> Q; 46 Q.push(s); 47 d[s] = 0; 48 vis[s] = 1; 49 while (!Q.empty()){ 50 int x = Q.front(); 51 Q.pop(); 52 for (int i = 0; i<G[x].size(); i++){ 53 Edge& e = edges[G[x][i]]; 54 if (!vis[e.to] && e.cap>e.flow){ 55 vis[e.to] = 1; 56 d[e.to] = d[x] + 1; 57 Q.push(e.to); 58 } 59 } 60 } 61 return vis[t]; 62 } 63 int DFS(int x, int a){ 64 if (x == t || a == 0)return a; 65 int flow = 0, f; 66 for (int& i = cur[x]; i<G[x].size(); i++){ 67 Edge& e = edges[G[x][i]]; 68 if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow)))>0){ 69 e.flow += f; 70 edges[G[x][i] ^ 1].flow -= f; 71 flow += f; 72 a -= f; 73 if (a == 0)break; 74 } 75 } 76 return flow; 77 } 78 int Maxflow(int s, int t, int need){ 79 this->s = s; this->t = t; 80 int flow = 0; 81 while (BFS()){ 82 memset(cur, 0, sizeof(cur)); 83 flow += DFS(s, INF); 84 if (flow > need)return flow; 85 } 86 return flow; 87 } 88 //最小割割边 89 vector<int> Mincut(){ 90 BFS(); 91 vector<int> ans; 92 for (int i = 0; i<edges.size(); i++){ 93 Edge& e = edges[i]; 94 if (vis[e.from] && !vis[e.to] && e.cap>0)ans.push_back(i); 95 } 96 return ans; 97 } 98 void Reduce(){ 99 for (int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow; 100 } 101 void ClearFlow(){ 102 for (int i = 0; i < edges.size(); i++) edges[i].flow = 0; 103 } 104 }; 105 Dinic ex; 106 int main(){ 107 int N, E, C, cas = 0; 108 while (~scanf("%d%d%d", &N, &E, &C)) 109 { 110 if (!N)break; 111 ex.init(N); 112 int a, b, c; 113 while (E--) 114 { 115 scanf("%d%d%d", &a, &b, &c); 116 ex.AddEdge(a, b, c); 117 } 118 int flow = ex.Maxflow(1, N, INF); 119 printf("Case %d: ", ++cas); 120 if (flow > C)printf("possible "); 121 else{ 122 vector<int> cut = ex.Mincut(); 123 ex.Reduce(); 124 vector<Edge>ans; 125 for (int i = 0; i < cut.size(); i++){ 126 Edge& e = ex.edges[cut[i]]; 127 int temp = e.cap; 128 e.cap = C; 129 ex.ClearFlow(); 130 if (flow + ex.Maxflow(1, N, C - flow) >= C)ans.push_back(e); 131 e.cap = temp; 132 } 133 if (ans.empty())printf("not possible "); 134 else{ 135 sort(ans.begin(), ans.end(), comp); 136 printf("possible option:(%d,%d)", ans[0].from, ans[0].to); 137 for (int i = 1; i < ans.size(); i++) 138 printf(",(%d,%d)", ans[i].from, ans[i].to); 139 printf(" "); 140 } 141 } 142 } 143 return 0; 144 }