解析见注释。。。。。。
#include<iostream>
#include<list>
#include<queue>
#include<set>
#include<memory>
#include<cstring>
using namespace std;
int t,p,I,total;
int x[30],up[30], down[30], p_length[30],water[30];
list<pair<int, int> > pipe[30];//对应的水面高度以及管道的编号
int target, level;
priority_queue<pair<int, int> > pq;
bool answer;
set<int> link;
void solve(){
while (!pq.empty()) pq.pop();
water[0] = down[0];
pq.push(make_pair(water[0],0));
while (!pq.empty()){
int height = pq.top().first;
int number = pq.top().second;
pq.pop();
if (number == -1) break;//表示溢出
if (number == -2){//表示可以淹没level
answer = true;
break;
}
total += (water[number]-height);
water[number] = height;
while (!pipe[number].empty()
&& pipe[number].front().first == height){
int flag = pipe[number].front().second;
if (flag < 0){
pq.push(pipe[number].front());
}
else if (water[flag]==-1){
water[flag] = down[flag];
pq.push(make_pair(water[flag],flag));
}
pipe[number].pop_front();
}
if (!pipe[number].empty())
pq.push(make_pair(pipe[number].front().first,number));
}
}
int main(){
cin >> t;//输入Case数量
while (t--){
link.clear();//每一次处理之前清空link
cin >> p;//管道的数量
memset(water,-1,sizeof(water));
for (int i = 0; i < p; i++){
cin >> x[i] >> up[i] >> p_length[i];//输入对应管道的信息
down[i] = up[i] + p_length[i];//计算出对应管道的下平面位置
pipe[i].clear();
}
cin >> I;//输入连接的数量
int px, py, length;
for (int i = 0; i < I; i++){
cin >> px >> py >> length;//输入每个连接的信息
int l_index = -1, r_index = -1;
for (int j = 0; j < p; j++){
if (py >= up[j] && py <= down[j]){
if (x[j] + 1 == px) l_index = j;
else if (x[j] == px + length) r_index = j;
if (l_index != -1 && r_index != -1) break;
}
}
pipe[l_index].push_back(make_pair(py,r_index));//对应的管道存储连接的长度以及另外一个管道的编号
pipe[r_index].push_back(make_pair(py,l_index));
link.insert(py);
}
cin >> target >> level;//输入目标管道的编号以及蜘蛛的位置
target--;//在本代码中管道编号从0开始所以需要减一
link.insert(level);//蜘蛛位置的y坐标也存入
if (!(level >= up[target] && level <= down[target])){
cout << "No Solution" << endl;
continue;
}
pipe[target].push_back(make_pair(level,-2));
for (int i = 0; i < p; i++){//对于每个管道,查看其长度范围内是否有连接,
//如果有,就在此y值出将其自己与自己连接,便于后续的处理
for (set<int>::iterator it = link.lower_bound(up[i]);
it != link.end()&&*it<down[i]; it++){
pipe[i].push_back(make_pair(*it,i));
}
pipe[i].push_back(make_pair(up[i],-1));//假设管道的顶端是和编号为-1的管道相连接的,这样便于
//进行后续的溢出判断
pipe[i].sort();
pipe[i].reverse();
}
answer = false;
total = 0;
solve();
if (answer) cout << total << endl;
else cout << "No Solution" << endl;
}
/*system("pause");*/
return 0;
}