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\n");
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\n");
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("\n");
140 }
141 }
142 }
143 return 0;
144 }