P3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一

还是蛮简单的一道题,首先dfs一遍,在所有能到达放有干草的洞穴的所有路径中,找出路径上最小伐值的最大值,按这个值由小到大,再来一遍贪心就行了,能放就放,不能放拉倒(也可以理解为,不能放把最前一个删了)。

但是如果题目改为每个洞穴不止一堆干草的话,也是没有问题的,只要在队列上在维护一个小根堆,判断队列中最小的干草堆是否比当前小,小则替换,否则不变。

 1 const maxn=200;
 2 type
 3   node=record
 4     f,t,w:longint;
 5   end;
 6 var n,i,j,m,k,u,v,x,now,ans:longint;
 7 head:array[0..101] of longint;
 8 b:array[0..2001] of node;
 9 f:array[0..100000] of longint;
10 p:array[0..101] of boolean;
11 a:array[0..15] of longint;
12 max:array[0..101] of longint;
13 function min(a,b:longint):longint;
14 begin
15   if a>b then exit(b)
16     else exit(a);
17 end;
18 procedure insert(num,u,v,x:longint);
19 begin
20   b[num].f:=head[u];
21   b[num].t:=v;
22   b[num].w:=x;
23   head[u]:=num;
24 end;
25 procedure qs(t,w:longint);
26 var mid,l,r,tem:longint;
27 begin
28   l:=t; r:=w; mid:=max[a[(l+r) shr 1]];
29   repeat
30     begin
31       while max[a[l]]<mid do inc(l);
32       while max[a[r]]>mid do dec(r);
33       if l<=r then
34         begin
35           tem:=a[l];
36           a[l]:=a[r];
37           a[r]:=tem;
38           inc(l);
39           dec(r);
40         end;
41     end;
42   until l>r;
43   if t<r then qs(t,r);
44   if l<w then qs(l,w);
45 end;
46 procedure bfs;
47 var now,nowe,l,r:longint;
48 begin
49   fillchar(max,sizeof(max),0);
50   fillchar(p,sizeof(p),true);
51   l:=1; r:=1; f[1]:=1; max[1]:=maxn;
52   while l<=r do
53     begin
54       now:=f[l];
55       nowe:=head[now];
56       while nowe<>0 do
57         begin
58           if min(max[now],b[nowe].w)>max[b[nowe].t] then
59             begin
60               max[b[nowe].t]:=min(max[now],b[nowe].w);
61               if p[b[nowe].t] then
62                 begin
63                   p[b[nowe].t]:=false;
64                   inc(r);
65                   f[r]:=b[nowe].t;
66                 end;
67             end;
68           nowe:=b[nowe].f;
69         end;
70       inc(l);
71       p[now]:=true;
72     end;
73 end;
74 begin
75   readln(n,m,k);
76   for i:=1 to k do
77     readln(a[i]);
78   for i:=1 to m do
79     begin
80       readln(u,v,x);
81       insert(2*i-1,u,v,x);
82       insert(2*i,v,u,x);
83     end;
84   bfs;
85   qs(1,k);
86   now:=1;
87   while (max[a[now]]=0) and (now<=k) do inc(now); //q[1]:=now;
88   if now<>k+1 then ans:=1
89     else begin
90       writeln(0);
91       halt;
92     end;
93   for i:=now+1 to k do
94     if max[a[i]]>ans then inc(ans);
95   writeln(ans);
96 end.

(转载请注明出处:http://www.cnblogs.com/Kalenda/)

时间: 2024-12-24 18:25:08

P3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一的相关文章

3381: [Usaco2004 Open]Cave Cows 2 洞穴里的牛之二

3381: [Usaco2004 Open]Cave Cows 2 洞穴里的牛之二 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 21  Solved: 18[Submit][Status][Discuss] Description 洞窟里有一道长长的通道.它由N(1≤N≤25000)段道尾相连构成,编号分别为1到N.每个通道有一个阈值,其范围在[1,10^9]依次通过i..j的通道,那奶牛的体重指数就不能超过i..j通道中阈值的最小值.贝茜有Q

Bzoj 3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一

3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 64  Solved: 37[Submit][Status][Discuss] Description 很少人知道其实奶牛非常喜欢到洞穴里面去探险. 洞窟里有N(1≤N≤100)个洞室,由M(1≤M≤1000)条双向通道连接着它们.每对洞室间 至多只有一条双向通道.有K(1≤K≤14)个洞室,里面放有1捆干草.牛吃1捆

bzoj3380[Usaco2004 Open]Cave Cows 1 洞穴里的牛之一*

bzoj3380[Usaco2004 Open]Cave Cows 1 洞穴里的牛之一 题意: 给一个无向图,每一条边都有一个阈值,有一些点有草.牛从点1出发,每当它到达有草的点可以选择吃或不吃,如果吃的话体重加1.对于边如果它的阈值小于牛的体重,则此边不可通过.求牛走一圈回到点1的最大体重.有草节点数≤14.点数≤100,边数≤1000. 题解: f[i][S]表示当前点为i,草状态为S的状态能否达到.具体看代码. 代码: 1 #include <cstdio> 2 #include <

bzoj3382[Usaco2004 Open]Cave Cows 3 洞穴里的牛之三*

bzoj3382[Usaco2004 Open]Cave Cows 3 洞穴里的牛之三 题意: n个点,求最远曼哈顿距离.n≤50000. 题解: 曼哈顿距离转切比雪夫距离(点(x,y)变为点(x+y,x-y)),然后输出最大横坐标-最小横坐标与最大纵坐标-最小纵坐标的较大值即可. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(in

bzoj3383[Usaco2004 Open]Cave Cows 4 洞穴里的牛之四*

bzoj3383[Usaco2004 Open]Cave Cows 4 洞穴里的牛之四 题意: 平面直角坐标系有n个点,从(0,0)出发,从一个点上可以跳到所有与它横纵坐标距离都≤2的点上,求最少步数使得纵坐标为T. 题解: 先用set存下所有的点.在做dp的时候把所有横纵坐标与当前节点距离≤2的节点都在set中查找,如果可以查到则可以转移到那个节点. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algor

bzoj3381[Usaco2004 Open]Cave Cows 2 洞穴里的牛之二*

bzoj3381[Usaco2004 Open]Cave Cows 2 洞穴里的牛之二 题意: RMQ问题.序列长度≤25000,问题数≤25000. 题解: 倍增. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define maxn 25100 6 using namespace

P3381: [Usaco2004 Open]Cave Cows 2 洞穴里的牛之二

这题..思维上远没有上一题复杂,是一个裸的RMQ..利用倍增就可以解决了. 1 var n,q,i,j,f,t,c:longint; 2 a:array[0..20,0..25001] of longint; 3 function min(a,b:longint):longint; 4 begin 5 if a>b then exit(b) 6 else exit(a); 7 end; 8 begin 9 readln(n,q); 10 for i:=1 to n do 11 readln(a[

P3382: [Usaco2004 Open]Cave Cows 3 洞穴里的牛之三

首先,我们先确定,最长的曼哈顿距离只可能为 x1+y2-(x2+y2) 和 x1-y1-(x2-y2) 所以我们只需要维护四个值, 分别代表 max(x+y) ; max(x-y) ; min(x+y) ; min(x-y) ; 因此答案也就是 max(max(x+y)-min(x+y),max(x-y)-min(x-y)). 1 const maxn=3000000; 2 var maxadd,minadd,maxdec,mindec,i,a,b,n:longint; 3 function m

P3383: [Usaco2004 Open]Cave Cows 4 洞穴里的牛之四

这个系列总算是做完了,这是我第一次高效率做完四道题,虽然中间有两道水题,但是第一和第四题还是蛮好的,但是只要能想到思路就很快能打完的. 像这道题,刚开始在想能不能用DP?但是苦于不知道怎么实施,后来又想,这么多点,有点像最短路径,但是总共有50000个点,边数有可能N*N吗? 于是我拿起笔算了一下,发现连边的话,先按X轴由小到大排序一遍,然后往后找 X 比当前点大 <=2 的 X,再通过比较 Y 之间的关系,只要相差不超过 2 就连接一条双向边,这样后面的点就不需要往前找了,但有人会问,会不会是