所以这道题卡链式前向星/必须快读吗?
查看原帖
所以这道题卡链式前向星/必须快读吗?
833124
BIOS楼主2023/9/29 20:49

我是刘汝佳紫书来的,没见过循环流,拿这道题试试。按照书上思路写完交上去是TLE,跟第二篇题解对照了一下,思路都是一样的,我在想是不是解法有问题。但是我交题解就能过,用我自己的就TLE。我们两个在实现上的区别就只有:链式前向星-邻接表,scanf-快读。所以能不能帮我看看是我代码假了还是这题单纯卡快读/链式前向星呢?

#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
const int N = 120, M = 1e6 + 5, INF = 0x3f3f3f3f, inf = 1e9;
int h[N], e[M], ne[M], st[N], f[N], pre[N], in[N], du[N];
int n, m, idx, S, T, kase, p, a, b;
double w[M], x, y, dist[N], xx, yy, tot;
struct node
{
    int x, y;
} ee[N];
vector<int> ac[N];
void add(int a, int b, int c, double d)
{
    e[idx] = b, ne[idx] = h[a], f[idx] = c, w[idx] = d, h[a] = idx++;
    e[idx] = a, ne[idx] = h[b], f[idx] = 0, w[idx] = -d, h[b] = idx++;
}
double get_dist(node a, node b)
{
    double dx = a.x - b.x, dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}
bool spfa()
{
    memset(in, 0, sizeof(in));
    for (int i = 0; i <= n + 1; i++)
        dist[i] = inf;
    queue<int> q;
    q.push(S), dist[S] = 0, st[S] = true, in[S] = INF;
    while (q.size())
    {
        int t = q.front();
        q.pop(), st[t] = false;
        for (int i = h[t]; ~i; i = ne[i])
        {
            int j = e[i];
            if (f[i] && dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i], pre[j] = i, in[j] = min(in[t], f[i]);
                if (!st[j])
                    q.push(j), st[j] = true;
            }
        }
    }
    return in[T] > 0;
}
double SSP()
{
    double cost = 0;
    while (spfa())
    {
        int t = in[T];
        cost += dist[T] * t;
        for (int i = T; i != S; i = e[pre[i] ^ 1])
            f[pre[i]] -= t, f[pre[i] ^ 1] += t;
    }
    return cost;
}
int main()
{
    while (scanf("%d%lf%lf", &n, &x, &y) ^ 1)
    {
        memset(h, -1, sizeof(h)), idx = 0, tot = 0, memset(du, 0, sizeof(du));
        S = 0, T = n + 1;
        for (int i = 1; i <= n; i++)
            ac[i].clear();
        for (int i = 1; i <= n; i++)
        {
            scanf("%d%d", &a, &b), ee[i] = {a, b};
            scanf("%d", &p);
            while (p)
                ac[i].push_back(p), scanf("%d", &p);
        }
        for (int i = 1; i <= n; i++)
            for (int j = 0; j < ac[i].size(); j++)
            {
                double w = y - get_dist(ee[i], ee[ac[i][j]]) * x;
                if (w > 0)
                    add(i, ac[i][j], 1, w);
                else
                    add(ac[i][j], i, 1, -w), du[ac[i][j]]++, du[i]--, tot += w;
            }
        for (int i = 1; i <= n; i++)
        {
            if (du[i] > 0)
                add(S, i, du[i], 0);
            if (du[i] < 0)
                add(i, T, -du[i], 0);
        }
        printf("Case %d: %.2f\n", ++kase, -(tot + SSP()) + 1e-8);
    }
}

2023/9/29 20:49
加载中...