2023ICPC网络赛第二场

  • define时间:
#define itn int
#define int long long
#define ind long double
#define yes cout << "Yes"
#define no cout << "No"
#define pii pair<long long, long long>
#define pci pair<char, int>
#define re return;

M Dirty Work

签到。分别算出一次通过和两次通过花的时间,从小到大排序即可。

void solve()
{
    cin >> n;
    ind ans = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i] >> b[i] >> f[i];
        g[i] = (a[i] + b[i]) * f[i] + a[i] * (1 - f[i]);
    }
    sort(g + 1, g + 1 + n);
    ind num = 0;
    for (itn i = 1; i <= n; i++)
    {
        num += g[i];
        ans += num;
    }
    printf("%.10lf", ans);
}

D Project Manhattan

签到。如果是负数,直接加上,并且给该行该列打上标记。

再分别遍历行、列,求解选取所有行、列需要的最小值。

void solve()
{
    cin >> n;
    sum = 0;
    for (int i = 1; i <= n; i++)
    {
        b[i] = c[i] = 0;
        d[i] = f[i] = inf;
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            cin >> a[i][j];
            if (a[i][j] <= 0)
            {
                sum += a[i][j];
                b[i] = 1;
                c[j] = 1;
            }
        }
    }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            d[i] = min(d[i], a[i][j]);
        }
    for (int j = 1; j <= n; j++)
        for (int i = 1; i <= n; i++)
        {
            f[j] = min(f[j], a[i][j]);
        }
    int l = 0, r = 0;
    for (int i = 1; i <= n; i++)
    {
        if (b[i])
            continue;
        else
            l += d[i];
    }

    for (int j = 1; j <= n; j++)
    {
        if (c[j])
            continue;
        else
            r += f[j];
    }
    cout << min(l, r) + sum;
}

I Impatient Patient

推公式。

f[i]:第 i 个点成功的\(=\)成功 \(*\) 1\(+\)失败 \(*\) 返回 \(a[i]\) 后再走到 i 点

x:成功概率

容易知道:\(f[i]=x+(1-x)*(f[i]+i-a[i]+1)\)

整理得到:

\[f[i] = \frac{x + (1 - x) * (i - a[i] + 1)}{x} \]

void solve()
{
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++)
    {
        cin >> b[i];
    }
    ind ans = n;
    for (int i = 0; i < n; i++)
    {
        if (b[i] == 0)
            continue;
        ind x = b[i] * 1.0 / 100000;
        ind res = i + 1 + (1 - x) * (i - a[i] + 1) / x;
        ans = min(ans, res);
    }
    printf("%.10lf", ans);
}

E Another Bus Route Problem

bfs。

考虑从 1 开始,走到一个点就令 \(d[i]+1\),并且由于 \(a[i]\) 连接着 i ,所以走到 i 时,可以更新它的父节点 \(a[i]\)

void solve()
{
    cin >> n >> m;
    for (int i = 2; i <= n; i++)
    {
        cin >> a[i];
        d[i] = -1;
    }
    while (m--)
    {
        cin >> x >> y;
        e[x].emplace_back(y);
        e[y].emplace_back(x);
    }
    queue<int> q;
    q.push(1);
    d[1] = 0;
    while (q.size())
    {
        auto u = q.front();
        q.pop();
        for (auto i : e[u])
        {
            while (d[i] == -1)
            {
                d[i] = d[u] + 1;
                q.push(i);
                i = a[i];
            }
        }
    }
    for (int i = 2; i <= n; i++)
    {
        cout << d[i] << ' ';
    }
}
posted @ 2025-08-13 16:52  lengling  阅读(83)  评论(0)    收藏  举报