POJ 3498 March of the Penguins(网络流+枚举)

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

题目:

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 xiyini 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 ≤ xiyi≤ 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.

Sample Input

2
5 3.5
1 1 1 1
2 3 0 1
3 5 1 1
5 1 1 1
5 4 0 1
3 1.1
-1 0 5 10
0 0 3 9
2 0 1 1

Sample Output

1 2 4
-1

题意:n只企鹅跳冰块,每只最多跳d米,并且每只企鹅从当前冰块跳到另一个冰块上,当前冰块的寿命-1。问所有企鹅能否跳到同一块冰块上,如果可能的话,列举出所有可能性。题解:注意题目中冰块下标是从0开始的。构图:源点S(0点),1-n枚举每个终点,把每个冰块所在的点分割成i(入口)和i+n(出口)两个点。S与i点连接,容量为该冰块上原有企鹅的数目;i与i+n连接,容量为冰块的寿命;如果i冰块能够跳到j冰块,i+n和j连接,容量为INF。图构造好直接跑Dinic就可以啦。
  1 //POJ 3498
  2 #include <queue>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 using namespace std;
  8
  9 const int N=233;
 10 const int M=2*N*N;
 11 const int INF=0x3f3f3f3f;
 12 int n,s,t,cnt;
 13 int Head[N],Depth[N],cur[N],Map[N][N];
 14 int Next[M],V[M],W[M];
 15
 16 void init(){
 17     cnt=-1;
 18     memset(Head,-1,sizeof(Head));
 19     memset(Next,-1,sizeof(Next));
 20 }
 21
 22 void add_edge(int u,int v,int w){
 23     cnt++;Next[cnt]=Head[u];V[cnt]=v;W[cnt]=w;Head[u]=cnt;
 24     cnt++;Next[cnt]=Head[v];V[cnt]=u;W[cnt]=0;Head[v]=cnt;
 25 }
 26
 27 bool bfs(){
 28     queue <int> Q;
 29     while(!Q.empty()) Q.pop();
 30     memset(Depth,0,sizeof(Depth));
 31     Depth[s]=1;
 32     Q.push(s);
 33     while(!Q.empty()){
 34         int u=Q.front();Q.pop();
 35         for(int i=Head[u];i!=-1;i=Next[i]){
 36             if((W[i]>0)&&(Depth[V[i]]==0)){
 37                 Depth[V[i]]=Depth[u]+1;
 38                 Q.push(V[i]);
 39             }
 40         }
 41     }
 42     if(Depth[t]==0) return 0;
 43     return 1;
 44 }
 45
 46 int dfs(int u,int dist){
 47     if(u==t) return dist;
 48     for(int& i=cur[u];i!=-1;i=Next[i]){
 49         if((Depth[V[i]]==Depth[u]+1)&&W[i]!=0){
 50             int di=dfs(V[i],min(dist,W[i]));
 51             if(di>0){
 52                 W[i]-=di;
 53                 W[i^1]+=di;
 54                 return di;
 55             }
 56         }
 57     }
 58     return 0;
 59 }
 60
 61 int Dinic(){
 62     int ans=0;
 63     while(bfs()){
 64         for(int i=0;i<=2*n;i++) cur[i]=Head[i];
 65         while(int d=dfs(s,INF)) ans+=d;
 66     }
 67     return ans;
 68 }
 69
 70 struct TnT{
 71     double x,y;
 72     int n,m;
 73 }node[N];
 74
 75 double dis(TnT a,TnT b){
 76     return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
 77 }
 78
 79 int check(){
 80     for(int i=1;i<=n;i++) add_edge(s,i,node[i].n);
 81     for(int i=1;i<=n;i++) add_edge(i,i+n,node[i].m);
 82     for(int i=1;i<=n;i++)
 83     for(int j=1;j<=n;j++)
 84     if(Map[i][j]) add_edge(i+n,j,INF);
 85
 86     return Dinic();
 87
 88 }
 89
 90 int main(){
 91     int T;
 92     double d;
 93     scanf("%d",&T);
 94     while(T--){
 95         int sum=0;
 96         scanf("%d %lf",&n,&d);
 97         for(int i=1;i<=n;i++){
 98             scanf("%lf %lf %d %d",&node[i].x,&node[i].y,&node[i].n,&node[i].m);
 99             sum+=node[i].n;
100         }
101         for(int i=1;i<=n;i++){
102             for(int j=1;j<=n;j++){
103                 if(i==j) Map[i][j]=1;
104                 else if(dis(node[i],node[j])<=d*d) Map[i][j]=1;
105                 else Map[i][j]=0;
106             }
107         }
108         vector <int> ans;
109         for(int i=1;i<=n;i++){
110             init();s=0;t=i;
111             if(check()==sum) ans.push_back(i);
112         }
113         int len=ans.size();
114         if(len==0) printf("-1\n");
115         else{
116             for(int i=0;i<len;i++){
117                 if(i!=len-1) printf("%d ",ans[i]-1);
118                 else if(i==len-1) printf("%d\n",ans[i]-1);
119             }
120         }
121
122     }
123
124     return 0;
125 }
				
时间: 2024-08-06 11:19:15

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: 1988 Description Somewhere near the south pole, a number of penguins are standing on a number of ice floes. Being social animals, the penguins would l

poj 3498 March of the Penguins 点流量有限制的最大流

题意: 给n块浮冰的坐标,每块浮冰上的企鹅数和能承受跳起的次数,求有哪些浮冰能让企鹅能到一起. 分析: 拆点将点流量的限制转化为边流量的限制,求最大流. 代码: //poj 3498 //sep9 #include <iostream> #include <queue> #include <algorithm> #include <cmath> using namespace std; const int maxN=128; const int maxM=4

poj 3498 最大流

March of the Penguins Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 4809   Accepted: 2195 Description Somewhere near the south pole, a number of penguins are standing on a number of ice floes. Being social animals, the penguins would l

UVA 12125 - March of the Penguins(最大流)

UVA 12125 - March of the Penguins 题目链接 题意:给定一些冰块,每个冰块上有一些企鹅,每个冰块有一个可以跳出的次数限制,每个冰块位于一个坐标,现在每个企鹅跳跃力为d,问所有企鹅能否跳到一点上,如果可以输出所有落脚冰块,如果没有方案就打印-1 思路:最大流,拆点表示冰块次数限制,然后枚举落脚冰块建图跑最大流即可 代码: #include <cstdio> #include <cstring> #include <queue> #inclu

uva 12125 March of the Penguins (最大流)

uva 12125 March of the Penguins 题目大意:网格上有n(n<=100)片荷叶,初始时第i片荷叶上有ni只企鹅(0<=ni<=10).由于承受能力有限,第i片荷叶最多只能承受mi(1<=mi<=200)只企鹅从上米娜跳走.一只企鹅最多能跳D(D<=105)单位距离.要求所有企鹅在同一片荷叶上集合.问哪些荷叶可以成为企鹅们集合的地点. 解题思路:企鹅为什么不游泳--.每片荷叶是有容量的,所以每片荷叶都要进行拆点,拆成两个点,容量为这片荷叶所能承

POJ训练计划3422_Kaka&#39;s Matrix Travels(网络流/费用流)

解题报告 题目传送门 题意: 从n×n的矩阵的左上角走到右下角,每次只能向右和向下走,走到一个格子上加上格子的数,可以走k次.问最大的和是多少. 思路: 建图:每个格子掰成两个点,分别叫"出点","入点", 入点到出点间连一个容量1,费用为格子数的边,以及一个容量∞,费用0的边. 同时,一个格子的"出点"向它右.下的格子的"入点"连边,容量∞,费用0. 源点向(0,0)的入点连一个容量K的边,(N-1,N-1)的出点向汇点连一

POJ 1087 A Plug for UNIX(网络流之最大流)

题目地址:POJ 1087 不知道是谁把这题化为了二分最大匹配的专题里..于是也没多想就按照二分图的模型来建的(虽然当时觉得有点不大对...).后来发现二分最大匹配显然不行..有权值..直接来个最大流多方便..然后一直WA..后来仔细想了想..这根本就不能建二分图啊....这题跟二分图一点关系都没有.... 这题的建图思路是让源点与每一个设备的插座类型连边,让汇点与每一个插座连边.然后用floyd判断该设备能否通过转换转换成可以插的插座上.只要可以转换成的就连边,权值为INF.然后求一次最大流,

POJ 2455Secret Milking Machine(二分+网络流之最大流)

题目地址:POJ2455 手残真浪费时间啊..又拖到了今天才找出了错误..每晚两道题不知不觉又变回了每晚一道题...sad.. 第一次在isap中忘记调用bfs,第二次则是遍历的时候居然是从1开始遍历的...sad... 这题思路倒是很简单,就是有一个比较坑的地方,就是这里的重边要当两条边来用,以前受最短路什么的影响,直接把慢的删了,很明显不对...这里的两条重边都是可以走的. 建图思路是,将1当作源点,将n当作汇点.右边的地方就连边,注意是无向边.最后判断最大流是否等于道路条数.二分找最小值.

POJ 1274 The Perfect Stall (网络流-最大流)

The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18308   Accepted: 8328 Description Farmer John completed his new barn just last week, complete with all the latest milking technology. Unfortunately, due to engineering pr