Description
Input
Output
题目大意:M 个人要过河,,河宽为 W。河上有N个垃圾,给出垃圾的坐标以及垃圾能同时容纳的人数,现在这 M 个人一下能跳距离D,问最少需要多少时间才可以使所有人到达对岸。跳一步一秒。 (开始人都在 X 轴上.对岸可以看为 Y =W 的一条直线)
思路:二分答案,判定性的最大流。最少用时间1到达对岸,最后用时间N+M到达对岸(假设要经过全部垃圾并且全部垃圾都只能站一个人)。假设现在二分的答案为mid,那么对于每个垃圾分成mid-1份,每份代表一个时间,再每个时间分成两份P、P'。如果从X轴能走到某点P,那么对所有时间,S连一条边到P。如果从某点P能走到对岸,那么对所有时间,P'连一条边到T。然后对所有时间每个点P连一条边到P',容量为该点能同时站多少人。最后所有距离在D以内的,对每个时间t,连边(P,t)→(Q,t+1),(Q,t)→(P,t+1)。最大流即为用mid的时间能过去多少人。二分答案即可。这种做法正确是因为:每个点的时间t只能走到t+1的时间,而在每个时间里通过某一点的流量不大于该点的容量,在任何时刻都能从S出发和到达T。
另外
SAP(62MS):
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 using namespace std; 6 7 const int MAXN = 55 * 105 * 2; 8 const int MAXE = MAXN * 500; 9 const int INF = 0x7fff7fff; 10 11 struct SAP { 12 int vis[MAXN], head[MAXN]; 13 int gap[MAXN], dis[MAXN], pre[MAXN], cur[MAXN]; 14 int to[MAXE], flow[MAXE], next[MAXE]; 15 int ecnt, st, ed; 16 17 void init(int ss, int tt) { 18 memset(head, 0, sizeof(head)); 19 ecnt = 2; 20 st = ss; ed = tt; 21 } 22 23 void addEdge(int u,int v,int f) { 24 to[ecnt] = v; flow[ecnt] = f; next[ecnt] = head[u]; head[u] = ecnt++; 25 to[ecnt] = u; flow[ecnt] = 0; next[ecnt] = head[v]; head[v] = ecnt++; 26 } 27 28 int Max_flow() { 29 int ans = 0, minFlow = INF, n = ed, u; 30 for (int i = 0; i <= n; ++i){ 31 cur[i] = head[i]; 32 gap[i] = dis[i] = 0; 33 } 34 u = pre[st] = st; 35 gap[0] = n; 36 while (dis[st] < n){ 37 bool flag = false; 38 for (int &p = cur[u]; p; p = next[p]){ 39 int v = to[p]; 40 if (flow[p] > 0 && dis[u] == dis[v] + 1){ 41 flag = true; 42 minFlow = min(minFlow, flow[p]); 43 pre[v] = u; 44 u = v; 45 if(u == ed){ 46 ans += minFlow; 47 while (u != st){ 48 u = pre[u]; 49 flow[cur[u]] -= minFlow; 50 flow[cur[u] ^ 1] += minFlow; 51 } 52 minFlow = INF; 53 } 54 break; 55 } 56 } 57 if (flag) continue; 58 int minDis = n-1; 59 for (int p = head[u]; p; p = next[p]){ 60 int v = to[p]; 61 if (flow[p] && dis[v] < minDis){ 62 minDis = dis[v]; 63 cur[u] = p; 64 } 65 } 66 if (--gap[dis[u]] == 0) break; 67 gap[dis[u] = minDis+1]++; 68 u = pre[u]; 69 } 70 return ans; 71 } 72 } G; 73 74 const int MAX = 55; 75 76 struct Point { 77 int x, y, c; 78 }; 79 80 int dis2(const Point &a, const Point &b) { 81 int xx = a.x - b.x, yy = a.y - b.y; 82 return xx * xx + yy * yy; 83 } 84 85 int n, m, d, w; 86 Point rub[MAX]; 87 88 #define FOR(i, s, t) for(int i = s; i <= t; ++i) 89 #define get_num(i, t) ((i - 1) * 2 * (mid - 1) + 2 * (t - 1) + 1) 90 91 void solve() { 92 int left = 1, right = n + m + 1; 93 while(left < right) { 94 int mid = (left + right) >> 1; 95 int ss = n * (mid - 1) * 2 + 1, st = ss + 1, tt = ss + 2; 96 G.init(st, tt); 97 G.addEdge(st, ss, m); 98 FOR(i, 1, n) { 99 if(rub[i].y <= d) { 100 FOR(t, 1, mid - 1) G.addEdge(ss, get_num(i, t), INF); 101 } 102 if(rub[i].y + d >= w) { 103 FOR(t, 1, mid - 1) G.addEdge(get_num(i, t) + 1, tt, INF); 104 } 105 } 106 FOR(i, 1, n) FOR(t, 1, mid - 1) { 107 int num = get_num(i, t); 108 G.addEdge(num, num + 1, rub[i].c); 109 if(t < mid - 1) G.addEdge(num + 1, num + 2, INF); 110 } 111 FOR(i, 1, n) FOR(j, 1, n) { 112 if(i == j || dis2(rub[i], rub[j]) > d * d) continue; 113 FOR(t, 1, mid - 2) G.addEdge(get_num(i, t) + 1, get_num(j, t + 1), INF); 114 } 115 int ans = G.Max_flow(); 116 if(ans < m) left = mid + 1; 117 else right = mid; 118 //printf("%d %d\n", mid, ans); system("pause"); 119 } 120 if(right == n + m + 1) puts("IMPOSSIBLE"); 121 else printf("%d\n", right); 122 } 123 124 int main() { 125 scanf("%d%d%d%d", &n, &m, &d, &w); 126 FOR(i, 1, n) scanf("%d%d%d", &rub[i].x, &rub[i].y, &rub[i].c); 127 FOR(i, 1, n) if(rub[i].c > m) rub[i].c = m; 128 if(w <= d) printf("1\n"); 129 else solve(); 130 }
DINIC(15MS):
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 using namespace std; 6 7 const int MAXN = 55 * 105 * 2; 8 const int MAXE = MAXN * 500; 9 const int INF = 0x7fff7fff; 10 11 struct Dinic { 12 int n, m, st, ed, ecnt; 13 int vis[MAXN], head[MAXN]; 14 int cur[MAXN], d[MAXN]; 15 int to[MAXE], next[MAXE], flow[MAXE]; 16 17 void init(){ 18 memset(head,0,sizeof(head)); 19 ecnt = 2; 20 } 21 22 void addEdge(int u,int v,int f) { 23 to[ecnt] = v; flow[ecnt] = f; next[ecnt] = head[u]; head[u] = ecnt++; 24 to[ecnt] = u; flow[ecnt] = 0; next[ecnt] = head[v]; head[v] = ecnt++; 25 } 26 27 bool bfs() { 28 memset(vis, 0, sizeof(vis)); 29 queue<int> que; que.push(st); 30 d[st] = 0; vis[st] = true; 31 while(!que.empty()){ 32 int u = que.front(); que.pop(); 33 for(int p = head[u]; p; p = next[p]){ 34 int v = to[p]; 35 if (!vis[v] && flow[p] > 0){ 36 vis[v] = 1; 37 d[v] = d[u] + 1; 38 que.push(v); 39 if(v == ed) return true; 40 } 41 } 42 } 43 return vis[ed]; 44 } 45 46 int dfs(int u, int a) { 47 if(u == ed || a == 0) return a; 48 int outflow = 0, f; 49 for(int &p = cur[u]; p; p = next[p]){ 50 int v = to[p]; 51 if(d[u] + 1 == d[v] && (f = dfs(v, min(a, flow[p]))) > 0){ 52 flow[p] -= f; 53 flow[p ^ 1] += f; 54 outflow += f; 55 a -= f; 56 if(a == 0) break; 57 } 58 } 59 return outflow; 60 } 61 62 int Maxflow(int ss, int tt, int nn) { 63 st = ss; ed = tt; 64 int ans = 0; 65 while(bfs()){ 66 for(int i = 0; i <= ed; ++i) cur[i] = head[i]; 67 ans += dfs(st, INF); 68 } 69 return ans; 70 } 71 } G; 72 73 const int MAX = 55; 74 75 struct Point { 76 int x, y, c; 77 }; 78 79 int dis2(const Point &a, const Point &b) { 80 int xx = a.x - b.x, yy = a.y - b.y; 81 return xx * xx + yy * yy; 82 } 83 84 int n, m, d, w; 85 Point rub[MAX]; 86 87 #define FOR(i, s, t) for(int i = s; i <= t; ++i) 88 #define get_num(i, t) ((i - 1) * 2 * (mid - 1) + 2 * (t - 1) + 1) 89 90 void solve() { 91 int left = 1, right = n + m + 1; 92 while(left < right) { 93 int mid = (left + right) >> 1; 94 int ss = n * (mid - 1) * 2 + 1, st = ss + 1, tt = ss + 2; 95 G.init(); 96 G.addEdge(st, ss, m); 97 FOR(i, 1, n) { 98 if(rub[i].y <= d) { 99 FOR(t, 1, mid - 1) G.addEdge(ss, get_num(i, t), INF); 100 } 101 if(rub[i].y + d >= w) { 102 FOR(t, 1, mid - 1) G.addEdge(get_num(i, t) + 1, tt, INF); 103 } 104 } 105 FOR(i, 1, n) FOR(t, 1, mid - 1) { 106 int num = get_num(i, t); 107 G.addEdge(num, num + 1, rub[i].c); 108 if(t < mid - 1) G.addEdge(num + 1, num + 2, INF); 109 } 110 FOR(i, 1, n) FOR(j, 1, n) { 111 if(i == j || dis2(rub[i], rub[j]) > d * d) continue; 112 FOR(t, 1, mid - 2) G.addEdge(get_num(i, t) + 1, get_num(j, t + 1), INF); 113 } 114 int ans = G.Maxflow(st, tt, tt); 115 if(ans < m) left = mid + 1; 116 else right = mid; 117 //printf("%d %d\n", mid, ans); system("pause"); 118 } 119 if(right == n + m + 1) puts("IMPOSSIBLE"); 120 else printf("%d\n", right); 121 } 122 123 int main() { 124 scanf("%d%d%d%d", &n, &m, &d, &w); 125 FOR(i, 1, n) scanf("%d%d%d", &rub[i].x, &rub[i].y, &rub[i].c); 126 FOR(i, 1, n) if(rub[i].c > m) rub[i].c = m; 127 if(w <= d) printf("1\n"); 128 else solve(); 129 }
BFS+ISAP(15MS):
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 using namespace std; 6 7 const int MAXN = 53 * 105 * 2; 8 const int MAXE = MAXN * 100; 9 const int INF = 0x7fff7fff; 10 11 struct SAP { 12 int head[MAXN]; 13 int gap[MAXN], dis[MAXN], pre[MAXN], cur[MAXN]; 14 int to[MAXE], flow[MAXE], next[MAXE]; 15 int ecnt, st, ed, n; 16 17 void init(int ss, int tt, int nn) { 18 memset(head, 0, sizeof(head)); 19 ecnt = 2; 20 st = ss; ed = tt; n = nn; 21 } 22 23 void addEdge(int u,int v,int f) { 24 to[ecnt] = v; flow[ecnt] = f; next[ecnt] = head[u]; head[u] = ecnt++; 25 to[ecnt] = u; flow[ecnt] = 0; next[ecnt] = head[v]; head[v] = ecnt++; 26 } 27 28 void bfs() { 29 memset(dis, 0x3f, sizeof(dis)); 30 queue<int> que; que.push(ed); 31 dis[ed] = 0; 32 while(!que.empty()) { 33 int u = que.front(); que.pop(); 34 ++gap[dis[u]]; 35 for(int p = head[u]; p; p = next[p]) { 36 int v = to[p]; 37 if (dis[v] > n && flow[p ^ 1] > 0) { 38 dis[v] = dis[u] + 1; 39 que.push(v); 40 } 41 } 42 } 43 } 44 45 int Max_flow() { 46 int ans = 0, minFlow = INF, u; 47 for (int i = 0; i <= n; ++i){ 48 cur[i] = head[i]; 49 gap[i] = dis[i] = 0; 50 } 51 u = pre[st] = st; 52 //gap[0] = n; 53 bfs(); 54 while (dis[st] < n){ 55 bool flag = false; 56 for (int &p = cur[u]; p; p = next[p]){ 57 int v = to[p]; 58 if (flow[p] > 0 && dis[u] == dis[v] + 1){ 59 flag = true; 60 minFlow = min(minFlow, flow[p]); 61 pre[v] = u; 62 u = v; 63 if(u == ed){ 64 ans += minFlow; 65 while (u != st){ 66 u = pre[u]; 67 flow[cur[u]] -= minFlow; 68 flow[cur[u] ^ 1] += minFlow; 69 } 70 minFlow = INF; 71 } 72 break; 73 } 74 } 75 if (flag) continue; 76 int minDis = n-1; 77 for (int p = head[u]; p; p = next[p]){ 78 int v = to[p]; 79 if (flow[p] && dis[v] < minDis){ 80 minDis = dis[v]; 81 cur[u] = p; 82 } 83 } 84 if (--gap[dis[u]] == 0) break; 85 gap[dis[u] = minDis+1]++; 86 u = pre[u]; 87 } 88 return ans; 89 } 90 } G; 91 92 const int MAX = 55; 93 94 struct Point { 95 int x, y, c; 96 }; 97 98 int dis2(const Point &a, const Point &b) { 99 int xx = a.x - b.x, yy = a.y - b.y; 100 return xx * xx + yy * yy; 101 } 102 103 int n, m, d, w; 104 Point rub[MAX]; 105 106 #define FOR(i, s, t) for(int i = s; i <= t; ++i) 107 #define get_num(i, t) ((i - 1) * 2 * (mid - 1) + 2 * (t - 1) + 1) 108 109 void solve() { 110 int left = 1, right = n + m + 1; 111 while(left < right) { 112 int mid = (left + right) >> 1; 113 int ss = n * (mid - 1) * 2 + 1, st = ss + 1, tt = ss + 2; 114 G.init(st, tt, tt); 115 G.addEdge(st, ss, m); 116 FOR(i, 1, n) { 117 if(rub[i].y <= d) { 118 FOR(t, 1, mid - 1) G.addEdge(ss, get_num(i, t), INF); 119 } 120 if(rub[i].y + d >= w) { 121 FOR(t, 1, mid - 1) G.addEdge(get_num(i, t) + 1, tt, INF); 122 } 123 } 124 FOR(i, 1, n) FOR(t, 1, mid - 1) { 125 int num = get_num(i, t); 126 G.addEdge(num, num + 1, rub[i].c); 127 if(t < mid - 1) G.addEdge(num + 1, num + 2, INF); 128 } 129 FOR(i, 1, n) FOR(j, 1, n) { 130 if(i == j || dis2(rub[i], rub[j]) > d * d) continue; 131 FOR(t, 1, mid - 2) G.addEdge(get_num(i, t) + 1, get_num(j, t + 1), INF); 132 } 133 int ans = G.Max_flow(); 134 if(ans < m) left = mid + 1; 135 else right = mid; 136 //printf("%d %d\n", mid, ans); system("pause"); 137 } 138 if(right == n + m + 1) puts("IMPOSSIBLE"); 139 else printf("%d\n", right); 140 } 141 142 int main() { 143 scanf("%d%d%d%d", &n, &m, &d, &w); 144 FOR(i, 1, n) scanf("%d%d%d", &rub[i].x, &rub[i].y, &rub[i].c); 145 FOR(i, 1, n) if(rub[i].c > m) rub[i].c = m; 146 if(w <= d) printf("1\n"); 147 else solve(); 148 }