哪里被卡了

P2505 [HAOI2012] 道路

tai_chi @ 2023-10-28 12:26:23

跑 n 遍 dij 然后统计贡献,求问哪里复杂度假了还是被卡常了。


by tai_chi @ 2023-10-28 12:26:49

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define IOS                     \
    ios::sync_with_stdio(NULL); \
    cin.tie(NULL);              \
    cout.tie(NULL)
#define pii pair<int, int>
const int maxn = 15005, maxm = 50005, mod1 = 1e9 + 7, inf = 0x3f3f3f3f;
int n, m;
int head[maxn], tot;
struct node
{
    int v, w, nxt;
} e[maxm];
void add(int u, int v, int w)
{
    e[++tot].v = v;
    e[tot].w = w;
    e[tot].nxt = head[u];
    head[u] = tot;
}
int dis[maxn];
bool vis[maxn];
bool ins[maxn]; // 在最短路图中
int in[maxn];   // 入度
void dij(int st)
{
    memset(dis, inf, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    dis[st] = 0;
    priority_queue<pii> q; // dis v
    q.push({0, st});
    while (!q.empty())
    {
        pii now = q.top();
        q.pop();
        int u = now.second;
        for (int i = head[u]; i; i = e[i].nxt)
        {
            int v = e[i].v, w = e[i].w;
            if (dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                if (!vis[v])
                {
                    q.push({dis[v], v});
                }
            }
        }
    }
    memset(ins, 0, sizeof(ins));
    for (int u = 1; u <= n; u++)
    {
        for (int i = head[u]; i; i = e[i].nxt)
        {
            int v = e[i].v, w = e[i].w;
            if (dis[v] == dis[u] + w)
            {
                ins[i] = 1;
                in[v]++;
            }
        }
    }
}
int tp[maxn], t;
void topsort()
{
    memset(tp, 0, sizeof(tp));
    t = 0;
    queue<int> q;
    for (int i = 1; i <= n; i++)
    {
        if (!in[i])
        {
            tp[++t] = i;
            q.push(i);
        }
    }
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        for (int i = head[u]; i; i = e[i].nxt)
        {
            if (!ins[i])
                continue;
            int v = e[i].v;
            in[v]--;
            if (!in[v])
            {
                tp[++t] = v;
                q.push(v);
            }
        }
    }
}
int cnt1[maxn], cnt2[maxn];
int ans[maxm];
void solve(int st)
{
    memset(cnt1, 0, sizeof(cnt1));
    memset(cnt2, 0, sizeof(cnt2));
    cnt1[st] = 1;
    for (int i = 1; i <= n; i++)
    {
        int u = tp[i];
        for (int j = head[u]; j; j = e[j].nxt)
        {
            if (!ins[j])
                continue;
            int v = e[j].v;
            cnt1[v] += cnt1[u], cnt1[v] %= mod1;
        }
    }
    for (int i = 1; i <= n; i++)
    {
        cnt2[i] = 1;
    }
    for (int i = n; i >= 1; i--)
    {
        int u = tp[i];
        for (int j = head[u]; j; j = e[j].nxt)
        {
            if (!ins[j])
                continue;
            int v = e[j].v;
            cnt2[u] += cnt2[v], cnt2[u] %= mod1;
        }
    }
    for (int i = n; i >= 1; i--)
    {
        int u = tp[i];
        for (int j = head[u]; j; j = e[j].nxt)
        {
            if (!ins[j])
                continue;
            int v = e[j].v;
            ans[j] += cnt1[u] * cnt2[v] % mod1, ans[j] %= mod1;
        }
    }
}
signed main()
{
    IOS;
    cin >> n >> m;
    for (int i = 1; i <= m; i++)
    {
        int u, v, w;
        cin >> u >> v >> w;
        add(u, v, w);
    }
    for (int i = 1; i <= n; i++)
    {
        dij(i);
        topsort();
        solve(i);
    }
    for (int i = 1; i <= m; i++)
    {
        cout << ans[i] << endl;
    }
    return 0;
}

by tai_chi @ 2023-10-28 14:02:31

破案了,这题卡 dij,换成 spfa 过了。


by tai_chi @ 2023-10-28 15:54:01

案破错了,我自己 dij 写假了。。。

小丑竟是我自己


by JunYao0 @ 2023-10-30 17:47:54

6


|