題目: UVa - 12125 - March of the Penguins
題目說明
給定一些冰塊,每個冰塊上有一些企鵝,每個冰塊有一個可以跳出的次數限制,每個冰塊位於一個坐標,現在每個企鵝跳躍力為d,問所有企鵝能否跳到一點上,如果可以輸出所有落腳冰塊,如果沒有方案就打印 -1。
UVA 12125 - March of the Penguins(最大流)_Remilia’s-CSDN博客
解題思路
最大流,依照上面的說明建邊後使用 Dinic 求解即可。
參考解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| #include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = a; i < b; ++i) #define CLR(c) memset(c, 0, sizeof(c))
static auto __ = [] { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); return 0; }();
template <typename T> T QPOP(queue<T>& q) { T tmp = q.front(); q.pop(); return tmp; }
struct Point { int x; int y; int n; int m;
void read() { cin >> x >> y >> n >> m; } };
const int INF = (int)1e9; const int MXN = 205;
int S, T; int rn[MXN][MXN]; int l[MXN];
int N; double D; int tot; Point p[MXN];
double dist(const Point& l, const Point& r) { return sqrt(pow(l.x - r.x, 2) + pow(l.y - r.y, 2)); }
void read() { cin >> N >> D;
tot = 0; T = N * 2 + 1; FOR(i, 1, N + 1) p[i].read(), tot += p[i].n; }
void build(int u) { CLR(rn);
FOR(i, 1, N + 1) { rn[S][i] = p[i].n;
if (i == u) rn[u][u + N] = INF; else rn[i][i + N] = p[i].m;
FOR(j, i + 1, N + 1) { if (dist(p[i], p[j]) > D) continue; rn[i + N][j] = INF; rn[j + N][i] = INF; } }
rn[u + N][T] = INF; }
bool dinicBFS() { CLR(l);
queue<int> q; q.push(S); l[S] = 1;
while (!q.empty()) { int u = QPOP(q);
FOR(v, 0, T + 1) { if (l[v] || !rn[u][v]) continue; l[v] = l[u] + 1; q.push(v); } }
return l[T]; }
int dinicDFS(int u, int cp) { if (u == T) return cp;
int tmp = cp;
FOR(v, 0, T + 1 && tmp) { if (l[v] != l[u] + 1 || !rn[u][v]) continue; int bt = dinicDFS(v, min(rn[u][v], tmp)); rn[u][v] -= bt; rn[v][u] += bt; tmp -= bt; }
return cp - tmp; }
int maximumFlow() { int mf = 0; while (dinicBFS()) mf += dinicDFS(S, INF); return mf; }
void solve() { int cnt = 0;
FOR(i, 1, N + 1) { build(i); if (maximumFlow() == tot) { if (cnt++) cout << ' '; cout << i - 1; } }
if (!cnt) cout << "-1\n"; else cout << '\n'; }
int main() { int T; cin >> T; while (T--) { read(); solve(); } }
|
參考資料
UVA 12125 - March of the Penguins(最大流)_Remilia’s-CSDN博客