首页 > POJ 3498 March of the Penguins

POJ 3498 March of the Penguins

POJ_3498

    对于任何一点来讲,限制的是跳走的企鹅的数量,如果这个点不是终点,那么必然跳过来的企鹅都会跳走,因此实际上限制的是经过这个点的企鹅的数量,这样通过拆点来限制经过点的企鹅的数量就可以了。最后暴力一点,枚举每个点作为终点并判断一下就可以了。

#include
#include<string.h>
#include
#define MAXD 210
#define MAXM 40410
#define INF 0x3f3f3f3f
int N, first[MAXD], e, next[MAXM], v[MAXM], flow[MAXM];
int S, T, d[MAXD], q[MAXD], work[MAXD], list[MAXD], L, TOT;
double D;
struct Stone
{double x, y;int n, m;
}stone[MAXD];
double sqr(double x)
{return x * x;
}
void init()
{int i, j;TOT = 0;scanf("%d%lf", &N, &D);for(i = 0; i < N; i ++)scanf("%lf%lf%d%d", &stone[i].x, &stone[i].y, &stone[i].n, &stone[i].m), TOT += stone[i].n;
}
void add(int x, int y, int z)
{v[e] = y, flow[e] = z;next[e] = first[x], first[x] = e ++;
}
void build(int t)
{int i, j;S = 2 * N, T = t;memset(first, -1, sizeof(first[0]) * (N << 1 | 1)), e = 0;for(i = 0; i < N; i ++)add(i, i + N, stone[i].m), add(i + N, i, 0);for(i = 0; i < N; i ++)for(j = i + 1; j < N; j ++)if(sqr(D) >= sqr(stone[i].x - stone[j].x) + sqr(stone[i].y - stone[j].y))add(i + N, j, INF), add(j, i + N, 0), add(j + N, i, INF), add(i, j + N, 0);for(i = 0; i < N; i ++)if(stone[i].n)add(S, i, stone[i].n), add(i, S, 0);
}
int bfs()
{int i, j, rear = 0;memset(d, -1, sizeof(d[0]) * (N << 1 | 1));d[S] = 0, q[rear ++] = S;for(i = 0; i < rear; i ++)for(j = first[q[i]]; j != -1; j = next[j])if(flow[j] && d[v[j]] == -1){d[v[j]] = d[q[i]] + 1, q[rear ++] = v[j];if(v[j] == T) return 1;}return 0;
}
int dfs(int cur, int a)
{if(cur == T) return a;for(int &i = work[cur]; i != -1; i = next[i])if(flow[i] && d[v[i]] == d[cur] + 1)if(int t = dfs(v[i], std::min(a, flow[i]))){flow[i] -= t, flow[i ^ 1] += t;return t;}return 0;
}
int dinic()
{int ans = 0, t;while(bfs()){memcpy(work, first, sizeof(first[0]) * (N << 1 | 1));while(t = dfs(S, INF))ans += t;}return ans;
}
void solve()
{int i;L = 0;for(i = 0; i < N; i ++){build(i);if(dinic() == TOT)list[L ++] = i;}if(L == 0)printf("-1
");else{printf("%d", list[0]);for(i = 1; i < L; i ++) printf(" %d", list[i]);printf("
");}
}
int main()
{int t;scanf("%d", &t);while(t --){init();solve();}return 0;
}

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • 用python编写乘法口诀表的方法 发布时间:2020-08-25 11:46:35 来源:亿速云 阅读:60 作者:小新 用python编写乘法口诀表的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧! 第一种:使用for遍历循环嵌套for x in...

  • //很长一段时间我都只使用以下方式做数组循环,具体原因看数据 var aa = for (var i = 0, l = aa.length; i < l; i++) { var a = aa[i];} 数据采集图片来源于网友 很明显,for循环第二种方式完胜!!! 至于for in、forEach什么的,不知道甩他们多少...

  • 目录 1. Scene Graph Generation with External Knowledge and Image Reconstruction 2. Knowledge Acquisition for Visual Question Answering via Iterative Querying Author...

  • 基础题1: 输入一个正整数 n (1≤n≤10)和n 阶方阵a的元素,如果方阵a中的所有元素都沿主对角线对称,输出“Yes”, 否则,输出“No”。主对角线为从矩阵的左上角至右下角的连线,方阵a中的所有元素都沿主对角线对称指对所有i, k,a[i][k]和a[k][i]相等。输入输出示例如下: 输入: 3 1 2 3 4 5 6 7...

  • 程序流程控制 分支 顺序 循环 if switch&case 1 2 3 调整 break 1.6 前 switch(byte、short、char、int) 1.7 可放String 循环 while(次数不确定) do while for(确定次数) break(跳出本层循环) continue(跳出本次循环)     *   2...