/* 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 #include using namespace std; const int inf = 1<<25; typedef pair pii; int mark[200]; int n; int maxcost; int cost[200][200], rtime[200][200]; int cap[200][200], rcap[200][200]; int inc_bfs(int s, int t, int m) { queue q; q.push(s); mark[s] = s; while (!q.empty()) { int v = q.front(); q.pop(); for (int i = 0; i <= n+1; ++i) { if (mark[i] == -1 && rcap[v][i]) { mark[i] = v; q.push(i); } } } if (mark[t]==-1) return 0; int inc = inf, v = t; while (v != s) { inc = min(inc, rcap[mark[v]][v]); v = mark[v]; } v = t; while (v != s) { rcap[mark[v]][v] -= inc; rcap[v][mark[v]] += inc; v = mark[v]; } return inc; } int max_flow(int n, int s, int t) { int tot = 0, inc; do memset(mark, -1, sizeof(int)*n), tot += inc = inc_bfs(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 m, e; while (scanf("%d%d%d", &n, &m, &e) == 3) { fprintf(stderr, "Params: %d %d %d\n", n, m, e); for (int i = 0; i <= n+1; ++i) for (int j = 0; j <= n+1; ++j) rtime[i][j] = inf; for (int i = 0; i < e; ++i) { int a, b, phi; scanf("%d%d%d", &a, &b, &phi); rtime[tr(a,n)][tr(b,n)] = 2*phi; rtime[tr(b,n)][tr(a,n)] = 2*phi; } fprintf(stderr, "Dijkstra time\n"); int distl[2][200]; memset(cap, 0, sizeof(cap)); memset(rcap, 0, sizeof(rcap)); 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 (int i = 0; i <= n+1; ++i) if (dist[i] > d + rtime[v][i]) { q.erase(pii(dist[i], i)); q.insert(pii(dist[i] = d + rtime[v][i], i)); } } } fprintf(stderr, "Collect mobdist time\n"); e = 0; int mobdist[10000]; for (int i = 0; i <= n+1; ++i) for (int j = i+1; j <= n+1; ++j) { if (rtime[i][j] == inf) continue; int d = inf; for (int c = 0; c < 4; ++c) { int d1 = distl[0][(c&1) ? i : j]; int d2 = distl[1][(c&2) ? i : j]; if (c == 1 || c == 2) d1 >?= (d1 + d2 + rtime[i][j]) / 2; // different ends cost more d1 >?= d2; d 1) { int mid = (lo+hi)/2; int lim = mid; for (int i = 0; i <= n+1; ++i) for (int j = 0; j <= n+1; ++j) if (rtime[i][j] != inf) cap[i][j] = rcap[i][j] = (cost[i][j] > lim ? m+1 : 1); int flow = max_flow(n+2, n, n+1); fprintf(stderr, "flow with lim %d is %d/%d\n", lim, flow, m); if (flow <= m) hi = mid; else lo = mid; } if (hi == 500000) printf("Impossible\n"); else printf("%.2lf\n", hi/2.0); } }