【题目大意】
有一些竖直的圆筒状管子,管子间有理想的水平细管相连。一只蜘蛛停在某跟管子的某个高度上,从第一根管子往系统注水,问前往营救的老鼠有多长时间可以关闭热水阀门。
最终抽象为当水上升到指定位置的时候系统中的总水柱高度。
【解题思路】
AC思路:
(参考“狗狗40题搞完纪念“)从第一根管子开始注水,采用优先队列的方式每次选取可注水且纵坐标最大(最低)的地方进行注水。若中途出现溢出现象,则永远都淹不到蜘蛛啦。
WA思路:
假设可以淹到蜘蛛,则蜘蛛所在管子的水柱高为其所在高度。从蜘蛛所在的管子根据管子的水平相连关系通过DFS的方式注水,看能否注水到第一根管子。注水途中判断是否溢出。
【解题吐槽】
WA了一个下午,决定还是在考完数理逻辑的下午不要太自虐。看了“狗狗40题搞完纪念“里的源码,把set、list、priority_queue的基本操作复习了一下。然后照着源代码的思路自己重新写了一遍(没有技术含量了╮(╯▽╰)╭)
物理不好还牵扯到做OJ呀,真的是o(╯□╰)o
【源代码】
/*
ZOJ1021
参考“狗狗40题搞完纪念“标程
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
#include <list>
#include <queue>
#include <cstdio>
#include <utility>
using namespace std;
#define maxp 30
int main()
{
int cases, pipes, links, target, level, tot_water;
int w,p,pp;
int px[maxp], py[maxp], bottom[maxp], water[maxp];
bool find_ans;
set<int> link;
list<pair<int, int> > e[maxp];
priority_queue<pair<int, int> > pq;
scanf("%d", &cases);
while (cases--)
{
//read data
scanf("%d", &pipes);
for (int i=0; i<pipes; i++)
{
int tmp;
scanf("%d%d%d", &px[i], &py[i], &tmp);
bottom[i]=py[i]+tmp; //bottom y-coordinate of the pipe
water[i]=-1; //means !visit pipe i
e[i].clear();
}
scanf("%d", &links);
link.clear();
for (int i=0; i<links; i++)
{
int lx, ly, len, lk1=-1, lk2=-1;
scanf("%d%d%d", &lx, &ly, &len);
for (int j=0; j<pipes; j++)
if (bottom[j]>=ly && py[j]<=ly)
{
if (px[j]+1==lx) lk1=j;
if (px[j]==lx+len) lk2=j;
if (lk1!=-1 && lk2!=-1)
{
break;
}
}
link.insert(ly);
e[lk1].push_back(make_pair(ly, lk2));
e[lk2].push_back(make_pair(ly, lk1));
}
scanf("%d%d", &target, &level);
link.insert(level);
target--;
//initial part
if (level<py[target])
{
printf("No Solution\n");
continue;
}
if (py[target]<=level && level<=bottom[target])
e[target].push_back(make_pair(level, -2));
for (int i=0; i<pipes; i++)
{
for (set<int>::const_iterator j=link.lower_bound(py[i]);
j!=link.end()&&*j<bottom[i]; j++)
{
e[i].push_back(make_pair(*j, i));
}
e[i].push_back(make_pair(py[i], -1));
e[i].sort();
e[i].reverse();
}
while (!pq.empty())
pq.pop();
water[0]=bottom[0];
pq.push(make_pair(water[0], 0));
find_ans=false;
tot_water=0;
//solve part
while (!pq.empty())
{
w=pq.top().first; //water
p=pq.top().second; //pipe
pq.pop();
if (p==-1)
break;
else if (p==-2)
{
find_ans=true;
break;
}
tot_water+=(water[p]-w);
water[p]=w;
while (!e[p].empty() && e[p].front().first==water[p])
{
pp=e[p].front().second;
if (pp<0)
{
pq.push(e[p].front());
}
else if (water[pp]==-1)
{
water[pp]=bottom[pp];
pq.push(make_pair(water[pp], pp));
}
e[p].pop_front();
}
if (!e[p].empty())
{
pq.push(make_pair(e[p].front().first, p));
}
}
if (find_ans)
printf("%d\n", tot_water);
else
printf("No Solution\n");
}
return 0;
}
————————————解题参考————————————
1、set标准库
2、list标准库
标准模板库(STL)学习探究之List容器
http://blog.youkuaiyun.com/sun_top/archive/2009/05/24/4212998.aspx
3、priority_queue标准库
标准模板库(STL)学习探究之List容器
http://blog.youkuaiyun.com/sun_top/archive/2009/05/25/4213413.aspx