Penguin

Description

在靠近南极的某处,一些企鹅站在许多漂浮的冰块上。由于企鹅是群居动物,所以它们想要聚集到一起,在同一个冰块上。企鹅们不想把自己的身体弄湿,所以它们在冰块之间跳跃,但是它们的跳跃距离,有一个上限。 
随着气温的升高,冰块开始融化,并出现了裂痕。而企鹅跳跃的压力,使得冰块的破裂加速。幸运的是,企鹅对冰块十分有研究,它们能知道每块冰块最多能承受多少次跳跃。对冰块的损害只在跳起的时候产生,而落地时并不对其产生伤害。 
现在让你来帮助企鹅选择一个冰面使得它们可以聚集到一起。 
Input

 

第一行整数N,和浮点数D,表示冰块的数目和企鹅的最大跳跃距离。 
(1≤N ≤100) (0 ≤D ≤100 000), 
接下来N行,xi, yi, ni and mi,分别表示冰块的X和Y坐标,该冰块上的企鹅数目,以及还能承受起跳的次数。 
• (−10 000 ≤ xi, yi ≤10 000, 0 ≤ ni ≤ 10, 1≤ mi ≤200). 

Output

输出所有可能的相聚冰块的编号,以0开始。如果不能相遇,输出-1。

Sample Input

 
  
 
    
样例1:
5 3.5
1 1 1 1
2 3 0 1
3 5 1 1
5 1 1 1
5 4 0 1

样例2:
3 1.1
- 1 0 5 10
0 0 3 9
2 0 1 1

 

Sample Output

 
  
 
    
1 2 4
- 1

 

 
    
1 var
2 flag:boolean;
3 ms:double;
4 n,m,k,i,j,t,ans,flow,sum,max:longint;
5 next,st,c,f,g: array [ 1 .. 1440000 ] of longint;
6 d,vd,x,y,p,s,prt,start,now: array [ 0 .. 1200 ] of longint;
7   procedure make(a,b,s:longint);
8   begin
9 inc(t);
10 if start[a] = 0 then start[a]: = t
11 else next[now[a]]: = t;
12 now[a]: = t;
13 st[t]: = b;
14 c[t]: = s;
15   end ;
16   function dfs(u,flow:longint):longint;
17   var
18 tmp,v,other,j:longint;
19 function min(a,b:longint):longint;
20 begin
21 if a < b then min: = a
22 else min: = b;
23 end ;
24 begin
25 if u = t then exit(flow);
26 dfs: = 0 ;
27 j: = start[u];
28 while j <> 0 do
29 begin
30 v: = st[j];
31 if (g[j] > 0 ) and (d[u] = d[v] + 1 ) then
32 begin
33 other: = j + ord(odd(j)) * 2 - 1 ;
34 tmp: = dfs(v,min(flow - dfs,g[j]));
35 dec(g[j],tmp);
36 inc(g[other],tmp);
37 inc(dfs,tmp);
38 if dfs = flow then exit(flow);
39 end ;
40 j: = next[j];
41 end ;
42 if d[ 0 ] > k then exit;
43 dec(vd[d[u]]);
44 if vd[d[u]] = 0 then d[ 0 ]: = k + 1 ;
45 inc(d[u]);
46 inc(vd[d[u]]);
47 end ;
48 begin
49 readln(n,ms);
50 m: = 0 ;
51 flag: = false;
52 t: = 0 ;
53 for i: = 1 to n do
54 begin
55 readln(x[i],y[i],p[i],s[i]);
56 inc(m,p[i]);
57 end ;
58 for i: = 1 to m do
59 begin
60 make( 0 ,i, 1 );
61 make(i, 0 , 0 );
62 end ;
63 k: = 0 ;
64 for i: = 1 to n do
65 begin
66 for j: = 1 to p[i] do
67 begin
68 make(k + j,m + i, 1 );
69 make(m + i,k + j, 0 );
70 end ;
71 k: = k + p[i];
72 end ;
73 k: = m + n * 2 ;
74 for i: = 1 to n do
75 begin
76 make(m + i,m + n + i,s[i]);
77 make(m + n + i,m + i, 0 );
78 for j: = 1 to n do
79 if (i <> j) and (sqr(x[i] - x[j]) + sqr(y[i] - y[j]) <= sqr(ms)) then
80 begin
81 make(m + n + i,m + j,maxlongint);
82 make(m + j,m + n + i, 0 );
83 end ;
84 end ;
85 max: = t;
86 for t: = m + 1 to m + n do
87 begin
88 for i: = 1 to max do
89 g[i]: = c[i];
90 fillchar(vd,sizeof(vd), 0 );
91 fillchar(d,sizeof(d), 0 );
92 vd[ 0 ]: = k + 1 ;
93 ans: = 0 ;
94 while d[ 0 ] <= k do
95 begin
96 flow: = dfs( 0 ,maxlongint);
97 ans: = ans + flow;
98 end ;
99 if ans = m then
100 begin
101 inc(sum);
102 prt[sum]: = t - m - 1 ;
103 flag: = true;
104 end ;
105 end ;
106 if flag then
107 begin
108 for i: = 1 to sum - 1 do
109 write(prt[i], ' ' );
110 writeln(prt[sum]);
111 end
112 else writeln( - 1 );
113 end .

 

转载于:https://www.cnblogs.com/PisntD/archive/2010/11/14/1876945.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值