POJ 3498 March of the Penguins(网络最大流)
Description
Somewhere near the south pole, a number of penguins are standing on a number of ice floes. Being social animals, the penguins would like to get together, all on the same floe. The penguins do not want to get wet, so they have use their limited jump distance to get together by jumping from piece to piece. However, temperatures have been high lately, and the floes are showing cracks, and they get damaged further by the force needed to jump to another floe. Fortunately the penguins are real experts on cracking ice floes, and know exactly how many times a penguin can jump off each floe before it disintegrates and disappears. Landing on an ice floe does not damage it. You have to help the penguins find all floes where they can meet.

A sample layout of ice floes with 3 penguins on them.
Input
On the first line one positive number: the number of testcases, at most 100. After that per testcase:
One line with the integer N (1 ≤ N ≤ 100) and a floating-point number D (0 ≤ D ≤ 100 000 ), denoting the number of ice pieces and the maximum distance a penguin can jump.
N lines, each line containing xi, yi, ni and mi, denoting for each ice piece its X and Y coordinate, the number of penguins on it and the maximum number of times a penguin can jump off this piece before it disappears ( −10 000 ≤ xi, yi ≤ 10 000 , 0 ≤ ni ≤ 10, 1 ≤ mi ≤ 200).
Output
Per testcase:
- One line containing a space-separated list of 0-based indices of the pieces on which all penguins can meet. If no such piece exists, output a line with the single number −1.
题目大意:有n块浮冰,每块冰上有ni只企鹅,他们最多能跳距离D,现在这些企鹅想在同一块冰上集中,但是呢,冰有裂缝,每块冰只能被企鹅在上面跳走mi次(跳进来和站在上面都不影响),问企鹅们可以集中在哪些浮冰上。
思路:拆点,每个点x拆成x和x',每个x到x'连边,容量为能跳多少次。然后如果i到j的距离不大于D,那么在i'到j连一条边,容量为无穷大。源点S到每一个点x连一条边,容量为有多少只企鹅在x上。最后,枚举每一个点x,x到汇点T连一条边,容量为无穷大,判断最大流是否等于企鹅的数量。
算法正确性说明:如此建图,每只企鹅都从源点开始走到汇点,但每个冰块只能经过cap[x->x']次,保证了企鹅只能从x跳走mi次。
PS:我枚举的时候,只是把前一条边的容量搞成0(要删掉好像好麻烦的样子),再新建一条从枚举点到汇点的边,这样就不用每次都建图了。
PS2:D居然是浮点数……还好没因此WA……
BFS+ISAP(235MS):
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std; const int MAXN = ;
const int MAXE = MAXN * MAXN * ;
const int INF = 0x3f3f3f3f; struct SAP {
int head[MAXN], dis[MAXN], gap[MAXN], pre[MAXN], cur[MAXN];
int to[MAXE], next[MAXE], flow[MAXE], cap[MAXE];
int st, ed, n, ecnt; void init() {
memset(head, , sizeof(head));
ecnt = ;
} void add_edge(int u, int v, int f) {
to[ecnt] = v; cap[ecnt] = f; flow[ecnt] = ; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; cap[ecnt] = ; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
//printf("%d->%d cap=%d\n", u, v, f);
} void bfs() {
memset(dis, 0x3f, sizeof(dis));
queue<int> que; que.push(ed);
dis[ed] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
++gap[dis[u]];
for(int p = head[u]; p; p = next[p]) {
int v = to[p];
if(dis[v] > n && cap[p ^ ]) {
dis[v] = dis[u] + ;
que.push(v);
}
}
}
} int Maxflow(int ss, int tt, int nn) {
st = ss, ed = tt, n = nn;
int ans = , minFlow = INF, u;
for(int i = ; i <= n; ++i) {
cur[i] = head[i];
gap[i] = ;
}
u = pre[st] = st;
bfs();
while(dis[st] < n) {
bool flag = false;
for(int &p = cur[u]; p; p = next[p]) {
int v = to[p];
if(cap[p] > flow[p] && dis[u] == dis[v] + ) {
flag = true;
minFlow = min(minFlow, cap[p] - flow[p]);
pre[v] = u;
u = v;
if(u == ed) {
ans += minFlow;
while(u != st) {
u = pre[u];
flow[cur[u]] += minFlow;
flow[cur[u] ^ ] -= minFlow;
}
minFlow = INF;
}
break;
}
}
if(flag) continue;
int minDis = n - ;
for(int p = head[u]; p; p = next[p]) {
int v = to[p];
if(cap[p] > flow[p] && dis[v] < minDis) {
minDis = dis[v];
cur[u] = p;
}
}
if(--gap[dis[u]] == ) break;
gap[dis[u] = minDis + ]++;
u = pre[u];
}
return ans;
}
} G; struct Point {
int x, y, n, m;
void read() {
scanf("%d%d%d%d", &x, &y, &n, &m);
}
}; double dist(const Point &a, const Point &b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
} int n, ss, tt;
int ans[], cnt;
double d;
Point p[]; void make_graph() {
ss = * n + , tt = ss + ;
G.init();
for(int i = ; i <= n; ++i)
if(p[i].n) G.add_edge(ss, * i - , p[i].n);
for(int i = ; i <= n; ++i) G.add_edge( * i - , * i, p[i].m);
for(int i = ; i <= n; ++i) {
for(int j = ; j <= n; ++j) {
if(i == j || dist(p[i], p[j]) > d) continue;
G.add_edge(i * , j * - , INF);
}
}
} int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%lf", &n, &d);
for(int i = ; i <= n; ++i) p[i].read();
int sum = ;
for(int i = ; i <= n; ++i) sum += p[i].n;
make_graph();
cnt = ;
for(int i = ; i <= n; ++i) {
G.add_edge(i * - , tt, INF);
memset(G.flow, , sizeof(G.flow));
if(sum == G.Maxflow(ss, tt, tt)) ans[++cnt] = i - ;
G.cap[G.ecnt - ] = ;
}
if(cnt == ) puts("-1");
else {
for(int i = ; i < cnt; ++i) printf("%d ", ans[i]);
printf("%d\n", ans[cnt]);
}
}
}
POJ 3498 March of the Penguins(网络最大流)的更多相关文章
- poj 3498 March of the Penguins(最大流+拆点)
题目大意:在南极生活着一些企鹅,这些企鹅站在一些冰块上,现在要让这些企鹅都跳到同一个冰块上.但是企鹅有最大的跳跃距离,每只企鹅从冰块上跳走时会给冰块造成损害,因此企鹅跳离每个冰块都有次数限制.找出企鹅 ...
- [POJ 3498] March of the Penguins
March of the Penguins Time Limit: 8000MS Memory Limit: 65536K Total Submissions: 4378 Accepted: ...
- poj 3498 March of the Penguins(拆点+枚举汇点 最大流)
March of the Penguins Time Limit: 8000MS Memory Limit: 65536K Total Submissions: 4873 Accepted: ...
- poj 1273 && hdu 1532 Drainage Ditches (网络最大流)
Drainage Ditches Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 53640 Accepted: 2044 ...
- UVALive-3972 March of the Penguins (最大流:节点容量)
题目大意:有n个带有裂缝的冰块.已知每个冰块的坐标和已经站在上面的企鹅数目,每当一个企鹅从一个冰块a跳到另一个冰块b上的时候,冰块a上的裂缝便增大一点,还知道每个冰块上最多能被跳跃的次数.所有的企鹅都 ...
- 【POJ3498】March of the Penguins(最大流,裂点)
题意:在靠近南极的某处,一些企鹅站在许多漂浮的冰块上.由于企鹅是群居动物,所以它们想要聚集到一起,在同一个冰块上.企鹅们不想把自己的身体弄湿,所以它们在冰块之间跳跃,但是它们的跳跃距离,有一个上限. ...
- poj 3498 最大流
March of the Penguins Time Limit: 8000MS Memory Limit: 65536K Total Submissions: 4809 Accepted: ...
- POJ--1087--A Plug for UNIX【Dinic】网络最大流
链接:http://poj.org/problem? id=1087 题意:提供n种插座.每种插座仅仅有一个,有m个设备须要使用插座,告诉你设备名称以及使用的插座类型,有k种转换器.能够把某种插座类型 ...
- P3376 【模板】网络最大流
P3376 [模板]网络最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点 ...
随机推荐
- 在vue-cli + webpack 项目中使用sass
1.准备工作: 由于npm的服务器在国外,网速慢而且安装容易失败,建议在安装之前,先安装国内的镜像,比如淘宝镜像 npm install -g cnpm --registry=https://regi ...
- STM32(13)——SPI
简介: SPI,Serial Peripheral interface串行外围设备接口. 接口应用在:EEPROM, FLASH,实时时钟,AD 转换器,还有数字信号处理器和数字信号解码器之间. 特点 ...
- python函数的四种参数传递方式
python中函数传递参数有四种形式 fun1(a,b,c) fun2(a=1,b=2,c=3) fun3(*args) fun4(**kargs) 四种中最常见是前两种,基本上一般点的教程都会涉及, ...
- Netty概述
一,介绍 Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. 也就是说,Netty 是一 ...
- 5、Java并发编程:Lock
Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.l ...
- spring cloud 服务注册中心eureka高可用集群搭建
spring cloud 服务注册中心eureka高可用集群搭建 一,准备工作 eureka可以类比zookeeper,本文用三台机器搭建集群,也就是说要启动三个eureka注册中心 1 本文三台eu ...
- #define NULL ((void *)0)引起的风波
1. 看下宏定义的结构体 typedef struct { ]; //CMEI/IMEI ]; //server ]; //CMEI/IMEI } Options; 2. 定义的NULL #defin ...
- javasript 字符串 数组操作
Javascript中经常涉及到对字符串和数组的处理,今天总结一下具体的用法 一 操作字符串 String对象有很多函数,可以以不同的方式访问和操作字符串,具体方法如下: charAt(index ...
- leetcode--笔记8 Fizz Buzz
题目要求: Write a program that outputs the string representation of numbers from 1 to n. But for multipl ...
- 如何实现最佳的跨平台游戏体验?Unity成亮解密实时渲染
7月31日,2018云创大会游戏论坛在杭州国际博览中心103B圆满举行.本场游戏论坛聚焦探讨了可能对游戏行业发展有重大推动的新技术.新实践,如AR.区块链.安全.大数据等. Unity大中华区技术经理 ...