// compile: make data
// run: ./data < data.in
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
std::ifstream terminal("/dev/tty");
#define PP cerr<<"\033[1;30mpause...\e[0m",terminal.ignore();
#else
#define debug(x...)
#define Debug(x...)
#define PP
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x),__VA_ARGS__})
#define cmax(x,...) x=max({(x),__VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
#define INF (int)(1152921504606846976)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
#define int long long
#define uint unsigned long long
#define MAXN 200010
struct network {
struct node {
int u, v, cap, f, w;
int idx;
bool operator<(const node &other) const {return w < other.w; }
bool operator==(const node &other) const {return v == other.v && w == other.w; }
};
vector<vector<node>> e;
vector<vector<int>> invid;
node &inv(node &edge) {return e[edge.v][invid[edge.u][edge.idx]]; }
int n, S, T;
vector<int> dep, cur;
network(int V) {
n = V;
e.resize(n), invid.resize(n), dep.resize(n), cur.resize(n);
}
void add_edge(int u, int v, int f, int w = 0) {
e[u].push_back(node{u, v, f, 0, w, sz(e[u])});
e[v].push_back(node{v, u, 0, 0, -w, sz(e[v])});
invid[u].push_back(sz(e[v]) - 1);
invid[v].push_back(sz(e[u]) - 1);
}
pair<int, int> mcmf(int s, int t) {
S = s, T = t;
vector<int> vis(n), dis(n);
int maxflow = 0, mincost = 0;
auto spfa = [&]() {
queue<int> q; q.push(S);
fill(dis.begin(), dis.end(), INF); dis[S] = 0;
vis[S] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
vis[u] = 0;
for (auto &edge: e[u]) {
int v = edge.v;
if (dis[v] > dis[u] + edge.w && edge.f < edge.cap) {
dis[v] = dis[u] + edge.w;
if (!vis[v]) q.push(v), vis[v] = 1;
}
}
}
return dis[T] != INF;
};
function<int(int, int)> dfs = [&](int u, int flow) {
if (u == T) return flow;
vis[u] = 1;
int ret = 0;
for (int &i = cur[u]; i < sz(e[u]); ++i) {
auto &edge = e[u][i];
int v = edge.v, d;
if (!vis[v] && edge.f < edge.cap && dis[v] == dis[u] + edge.w && (d = dfs(v, min(flow, edge.cap-edge.f)))) {
mincost += d * edge.w;
ret += d, edge.f += d;
flow -= d, inv(edge).f -= d;
if (!flow) break;
}
}
vis[u] = 0;
return ret;
};
while (spfa()) {
fill(cur.begin(), cur.end(), 0);
maxflow += dfs(S, INF);
}
return {maxflow, mincost};
}
void graphviz_dump(int plus = 0, string filename = "graph.dot") {
FILE *f = fopen(filename.c_str(), "w");
fprintf(f, "digraph {\n ");
rep(i, 0, n) fprintf(f, "%lld%s", i+plus, i==n-1 ? ";\n" : " ");
rep(u, 0, n) {
for (auto &edge: e[u]) {
int v = edge.v, cap = edge.cap;
if (!cap) continue;
fprintf(f, " %lld -> %lld \\n%lld\"];\n", u+plus, v+plus, edge.f, edge.cap, edge.w);
}
}
fprintf(f, "}\n");
}
};
int32_t main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int n, m, k; cin >> n >> m >> k;
network g(n+1);
rep(i, 0, m) {
int u, v; cin >> u >> v;
g.add_edge(u, v, 1, 1);
}
g.add_edge(0, 1, k, 0);
auto [flow, cost] = g.mcmf(0, n);
if (flow != k) {
cout << -1 << endl;
return 0;
}
cout << cost << endl;
while (k--) {
int x = 1;
vector<int> vs;
while (x != n) {
for (auto &edge: g.e[x]) {
if (edge.f == 1) {
vs.push_back(x);
edge.f = 0;
x = edge.v;
break;
}
}
}
vs.push_back(n);
cout << sz(vs) << endl;
rep(i, 0, sz(vs)) cout << vs[i] << " \n"[i==sz(vs)-1];
}
return 0;
}
No Comments