Gym 100685 F Flood

本文介绍了一个模拟洪水流动的问题,通过构建有向图并使用BFS算法模拟水流方向,最终计算出指定地点的水位高度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

F. Flood
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

We all know that King Triton doesn't like us and therefore shipwrecks, hurricanes and tsunami do happen. But being bored with the same routine all these years Triton has decided to make a spectacular flood this year.

He chose a small town in a hilly valley not far from the sea. The power of Triton is enough to pour one heavy rain on the hill. He is worried however that water will miss that chosen town due to various river basins and water flows. Triton asks you to help him help calculate the amount of water that reaches the chosen town.

There are water ponds in a hilly valley on the way to the town. Some of them are connected to each other with rivers. If some pond is overfull with water, the water begins to flow evenly to the connected ponds (or to the sea, if there are no connected ponds). Each pond contains some water initially, and the maximum pond capacity is also known. The chosen town is located on the bank of one pond — you should calculate the water level in this pond after all water flow is run out.

Input

On the first line of input integers N and K (2 ≤ N ≤ 104, 0 ≤ K ≤ 105) are given — the number of water ponds and the number of pond connections respectively.

On the next N lines of input integers Pi and Ai (0 ≤ Ai ≤ Pi ≤ 106) are given — these are the maximum ith water pond capacity and its initial water level.

On the next K lines of input integers Fj and Tj (1 ≤ Fj, Tj ≤ N, Fj ≠ Tj) are given — they denote a possible river flow connection from Fjto Tj water pond (reverse water flow is not possible). Consider water flow from a pond to be equally distributed between all possible flow connections from that pond. Triton is absolutely sure that there are no cycles in river flows between the ponds, and there are no multiple rivers between any two ponds.

On the last line of input integers XY and Z (1 ≤ X, Z ≤ N, 1 ≤ Y ≤ 106) are given — the water pond that receives Triton's heavy rain, the amount of water that is added to this pond and the target pond (near the chosen town) to test respectively.

Consider that excessive water flows from a water pond if and only if its capacity is full. If some pond is overfull and no water flows are defined from that pond consider that all excessive water has flown out to the sea.

Output

The first line of the output should contain a single floating-point number Lz — the final water level in the target pond when all water flow is complete. Answers with absolute or relative error less than 10 - 4 are considered correct.

Sample test(s)
input
4 4
10 10
1 0
1 0
10 0
1 2
1 3
2 4
3 4
1 5 4
output
3.0
题目链接:http://codeforces.com/gym/100685/problem/F

题目大意:给定一个有向图,每个点代表一个水塘,告诉你水塘的容积和初始存水量,有向边代表水的流向。然后告诉你X地点下了Y的雨量,问当所有的地区水静止后,Z点的水量。

思路:由于不会存在环(因为会造成无解),所以只需要从X点BFS出去,模拟水流的方向,一个小的要点在于记录每个点的入度数,每次有新的水流汇入的时候,将入度数减一,只有入度数为0时,将该点push入队列即可。复杂度O(n)

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <limits.h>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
#define pll pair<LL, LL>
#define pii pair<int, int>
#define X first
#define Y second
#define MAXN 100010//1e5
#define lson l, mid, (rt << 1)
#define rson mid + 1, r, (rt << 1 | 1)
const double eps = 1e-10;
int n, k, X, Z;
double Y;
struct node {
    double sum, now;
} input[MAXN];
vector<int> edge[MAXN];
int cnt[MAXN];
void init() {
    for(int i = 0; i <= n; i++) {
        edge[i].clear();
    }
    memset(cnt, 0, sizeof cnt);
}
void BFS() {
    queue<int> q;
    q.push(X);
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        node res = input[u];
        if(res.now <= res.sum) continue;
        input[u].now = input[u].sum;
        int len = edge[u].size();
        double add = (res.now - res.sum) / len;
        for(int i = 0; i < len; i++) {
            int v = edge[u][i];
            input[v].now += add;
            cnt[v]--;
            if(cnt[v] == 0) q.push(v);
        }
    }
}
int main() {
    while(~scanf("%d%d", &n, &k)) {
        init();
        double ans;
        for(int i = 1; i <= n; i++) {
            scanf("%lf%lf", &input[i].sum, &input[i].now);
        }
        int u, v;
        for(int i = 0; i < k; i++) {
            scanf("%d%d", &u, &v);
            edge[u].push_back(v);
            cnt[v]++;
        }
        scanf("%d%lf%d", &X, &Y, &Z);
        input[X].now += Y;
        BFS();
        ans = input[Z].now;
        printf("%.6lf\n", min(ans, input[Z].sum));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值