/* Sample solution to "Kingdom" from NCPC 2005 * Algorithm: dijkstra + ford-fulkerson, setting inf capacity on edges * where we won't allow placing of soldiers. * Author: Per Austrin */ #include #include #include using namespace std; struct edge { int from, to, rev; int cap, flow; int dist; edge(int from, int to, int rev, int dist): from(from), to(to), rev(rev), cap(1), flow(0), dist(dist) {} int res() { return cap - flow; } }; const int inf = 1<<25; typedef pair pii; typedef vector edges; void add_edge(edges *g, int from, int to, int dist) { g[from].push_back(edge(from, to, g[to].size(), dist)); g[to].push_back(edge(to, from, g[from].size()-1, dist)); } bool mark[200]; int inc_dfs(edges *g, int s, int t, int m) { int inc; if (s == t) return m; mark[s] = true; for (edges::iterator it = g[s].begin(); it != g[s].end(); ++it) if (!mark[it->to] && it->res() && (inc = inc_dfs(g, it->to, t, min(m, it->res())))) { it->flow += inc; g[it->to][it->rev].flow -= inc; return inc; } return 0; } int max_flow(edges *g, int n, int s, int t) { int tot = 0, inc; do memset(mark, 0, sizeof(bool)*n), tot += inc = inc_dfs(g, s, t, inf); while (inc); return tot; } int tr(int x, int n) { return x != 104729 ? x != 95050 ? x : n : n+1; } int main(void) { int n, m, e; while (scanf("%d%d%d", &n, &m, &e) == 3) { fprintf(stderr, "Params: %d %d %d\n", n, m, e); edges graph[200]; for (int i = 0; i < e; ++i) { int a, b, phi; scanf("%d%d%d", &a, &b, &phi); add_edge(graph, tr(a, n), tr(b, n), 2*phi); } fprintf(stderr, "Dijkstra time\n"); int distl[2][200]; memset(distl, 0x1f, sizeof(distl)); for (int s = n; s <= n+1; ++s) { int *dist = distl[s-n]; set q; dist[s] = 0; q.insert(pii(0, s)); while (!q.empty()) { int v = q.begin()->second, d = q.begin()->first; q.erase(q.begin()); for (edges::iterator it = graph[v].begin(); it != graph[v].end(); ++it) if (dist[it->to] > d + it->dist) { q.erase(pii(dist[it->to], it->to)); q.insert(pii(dist[it->to] = d + it->dist, it->to)); } } } fprintf(stderr, "Collect mobdist time\n"); e = 0; pair< int, edges::iterator > mobdist[10000]; for (int i = 0; i <= n+1; ++i) for (edges::iterator it = graph[i].begin(); it != graph[i].end(); ++it) if (it->to > i) { int d = inf; for (int c = 0; c < 4; ++c) { int d1 = distl[0][(c&1) ? it->from : it->to]; int d2 = distl[1][(c&2) ? it->from : it->to]; if (c == 1 || c == 2) d1 >?= (d1 + d2 + it->dist) / 2; // different ends cost more d1 >?= d2; d m) printf("Impossible\n"); else { for (; e--; ) { edges::iterator it = mobdist[e].second; it->cap = inf; graph[it->to][it->rev].cap = inf; flow += max_flow(graph, n+2, n, n+1); if (flow > m) { printf("%.1lf\n", mobdist[e].first/2.0); break; } } if (e < 0) printf("%.1lf\n", 0.0); } } }