https://vjudge.net/contest/68128#problem/J
/// 跑完最大流后的残余网络
/// 从源点及汇点开始 分别标记能到达的点
/// 遍历边 两端点标记不同即为割边
/// (源点不能到达的点必与汇点连通 标记源点能到达的点)
/// (遍历边 一端标记 一端未标记为割边)
#include <bits/stdc++.h>
using namespace std;
const long long inf = 1e18;
const int mn = 100, mm = 1500;
int ST[mm], ED[mm];
bool biao[mn][mn];
bool vis[mn];
int edge;
int fr[mn];
int lv[mn];
struct node
{
int to, nx, fan;
long long val;
} e[mm];
long long flow = 0;
void init()
{
flow = 0;
edge = 0;
memset(fr, -1, sizeof fr);
memset(vis, 0, sizeof vis);
memset(biao, 0, sizeof biao);
}
void addedge(int u, int v, long long w)
{
edge++;
e[edge].to = v, e[edge].val = w, e[edge].nx = fr[u], e[edge].fan = edge + 1;
fr[u] = edge;
edge++;
e[edge].to = u, e[edge].val = w, e[edge].nx = fr[v], e[edge].fan = edge - 1;
fr[v] = edge;
}
void bfs(int s)
{
memset(lv, 0, sizeof lv);
lv[s] = 1;
queue<int> q;
q.push(s);
while (!q.empty())
{
int t = q.front();
q.pop();
for (int i = fr[t]; i != -1; i = e[i].nx)
{
if (e[i].val > 0 && !lv[e[i].to])
{
lv[e[i].to] = lv[t] + 1;
q.push(e[i].to);
}
}
}
}
long long dfs(int s, int t, long long f)
{
if (s == t)
return f;
for (int i = fr[s]; i != -1; i = e[i].nx)
{
if (e[i].val > 0 && lv[s] < lv[e[i].to])
{
long long d = dfs(e[i].to, t, min(f, e[i].val));
if (d > 0)
{
e[i].val -= d;
e[e[i].fan].val += d;
return d;
}
}
}
return 0;
}
void max_flow(int s, int t)
{
while (1)
{
bfs(s);
if (!lv[t])
break;
long long f = 0;
while ((f = dfs(s, t, inf)) > 0)
flow += f;
}
}
void bfs2(int s)
{
queue<int> q;
q.push(s);
vis[s] = 1;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = fr[u]; i != -1; i = e[i].nx)
{
int v = e[i].to;
if (e[i].val > 0 && !vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
int main()
{
//freopen("D:\\in.txt", "r", stdin);
int n, m;
while (~scanf("%d %d", &n, &m) && (n || m))
{
init();
int st = 1, ed = 2;
for (int i = 1; i <= m; i++)
{
int a, b;
long long c;
scanf("%d %d %lld", &a, &b, &c);
ST[i] = a, ED[i] = b;
addedge(a, b, c);
}
max_flow(st, ed);
bfs2(st); /// 从源点开始bfs
for (int i = 1; i <= m; i++)
{
if ((vis[ST[i]] && !vis[ED[i]]) || (!vis[ST[i]] && vis[ED[i]]))
{
if (!biao[ST[i]][ED[i]]) // 去重
{
biao[ST[i]][ED[i]] = biao[ED[i]][ST[i]] = 1;
printf("%d %d\n", ST[i], ED[i]);
}
}
}
printf("\n");
}
return 0;
}