题目链接:http://poj.org/problem?id=3498

思路:首先设一个超级源点,将源点与各地相连,边容量为各点目前的企鹅数量,然后就是对每个冰块i进行拆点了(i,i+n),边容量为能够接受的受损程度,这样就把点权问题转化为边权问题了,然后就是对于那些能够相互跳跃的冰块之间连边(i+n,j),(j+n,i),边容量为inf。最后就是枚举汇点看是否等于总数。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define MAXN 222
#define MAXM 2222222
#define inf 1<<30 struct Edge{
int v,cap,next;
}edge[MAXM]; int n,NE,vs,vt,NV;
double dist;
int head[MAXN]; void Insert(int u,int v,int cap)
{
edge[NE].v=v;
edge[NE].cap=cap;
edge[NE].next=head[u];
head[u]=NE++; edge[NE].v=u;
edge[NE].cap=;
edge[NE].next=head[v];
head[v]=NE++;
} int level[MAXN],gap[MAXN];
void bfs(int vt)
{
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int>que;
que.push(vt);
while(!que.empty()){
int u=que.front();
que.pop();
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-)continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN],cur[MAXN];
int SAP(int vs,int vt)
{
bfs(vt);
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(cur));
int maxflow=,aug=inf;
int u=pre[vs]=vs;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap>&&level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
aug=min(aug,edge[i].cap);
if(v==vt){
maxflow+=aug;
for(u=pre[v];v!=vs;v=u,u=pre[u]){
edge[cur[u]].cap-=aug;
edge[cur[u]^].cap+=aug;
}
aug=inf;
}
break;
}
}
if(flag)continue;
int minlevel=NV;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap>&&level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==)break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return maxflow;
}
struct Point{
double x,y;
int num1,num2;
}p[MAXN]; double Get_dist(int i,int j)
{
double d1=(p[i].x-p[j].x)*(p[i].x-p[j].x);
double d2=(p[i].y-p[j].y)*(p[i].y-p[j].y);
return sqrt(d1+d2);
}
void Build()
{
NE=;
memset(head,-,sizeof(head));
vs=,NV=*n+;
for(int i=;i<=n;i++)Insert(vs,i,p[i].num1);
for(int i=;i<=n;i++)Insert(i,i+n,p[i].num2);
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(Get_dist(i,j)<=dist){
Insert(i+n,j,inf);
Insert(j+n,i,inf);
}
}
}
}
int ans[MAXN],cnt;
int main()
{
int _case,sum;
scanf("%d",&_case);
while(_case--){
scanf("%d%lf",&n,&dist);
sum=;
for(int i=;i<=n;i++){
scanf("%lf%lf%d%d",&p[i].x,&p[i].y,&p[i].num1,&p[i].num2);
sum+=p[i].num1;
}
cnt=;
for(int i=;i<=n;i++){
Build();
if(SAP(vs,i)==sum)ans[cnt++]=i;
}
if(cnt){
for(int i=;i<cnt;i++){
printf(i?" %d":"%d",ans[i]-);
}
printf("\n");
}else
puts("-1");
}
return ;
}

最新文章

  1. Android线程管理之Thread使用总结
  2. 在CentOS 7上安装Node.js的4种方法
  3. sqlserver复杂排序(order by case when)
  4. SQL Server数据库大型应用解决方案总结
  5. 给jdk写注释系列之jdk1.6容器(11)-Queue之ArrayDeque源码解析
  6. Xvfb+YSlow+ShowSlow搭建前端性能测试框架 - 前端技术 | TaoBaoUED
  7. unity3d ngui-TweenRotation-TweenPosition-TweenScale
  8. 201521123011 《Java程序设计》第8周学习总结
  9. 《mysql必知必会》读书笔记--安全管理及数据库维护
  10. idea为tomcat设置虚拟地址
  11. C#多线程编程(2)-- async,await基本用法
  12. Eclipse中JavaSwing图形插件安装
  13. Android P添加一个可以让system_server进程访问的hal service需要改动的sepolicy文件
  14. WebService常用接口链接(很全面,值得一看)
  15. dede后台登陆不了、出现index.htm Not Found!、无更新模板,解析不了
  16. bzoj2588 Spoj10628. count on a tree
  17. Cross Validation(交叉验证)
  18. C#配置文件
  19. 使用FormsAuthenticationTicket进行登陆验证
  20. Docker:集装箱式“运输”在软件上的实现

热门文章

  1. 算法笔记_050:硬币收集问题(Java)
  2. Vue 组件通信(子组件向父组件传递数据)
  3. 【Linux】压缩与解压
  4. iDempiere VS ADempiere
  5. HTML5&amp;amp;CSS3初学者指南
  6. 设置SSH编码为中文
  7. JS经验库
  8. Vivado Logic Analyzer的使用
  9. JAVA设计模式之 命令模式【Command Pattern】
  10. ZOJ 3703 Happy Programming Contest(0-1背包)