綿陽Dongchen国際test201909.29

爆発ゼロ磁場!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

私の思考プロセスについての講演:

n点、M双方向エッジ----> 圧縮点?

3色のみ、最大--------> dpの?

その後、私はちょうど外に出て行く上で保持なし

解決:

各色ユニコムでプレブロックの各点

すなわち、各色毎に図の集光点Tarjanを構築しました。

保守集光点後強いアタッチメントポイントと右の各成分の

それが描画されているので、複数のパスが存在する可能性があるため、

それをv、ポイントuのパスは、交差点に属していないかもしれないが、V、Uは交差点に属し、

だから我々は、使用マップをうまく維持します。

chitongziによってコード

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100000 + 5, M = 200000 + 5;
inline void read(int&a)
{
    a = 0; char k = getchar (); int f = 1;
    while (k > '9' || k < '0') { if (k == '-') f = -1; k = getchar (); }
    while (k >= '0' && k <= '9') { a = a * 10 + k - '0'; k = getchar (); }
    a *= f;
}
int c[N];
struct Graph {
    int fr[M << 1], to[M << 1], h[N], tot;
    int stk[N], top, dfn[N], low[N], dftot, color[N], cocnt, ans[N];
    int sumc[N];
    bool ins[N];
    inline void adde (int u, int v)
    {
        tot++;
        fr[tot] = h[u];
        to[tot] = v;
        h[u] = tot;
    }
    inline void tarjan (int p)
    {
        dfn[p] = ++dftot;
        ins[p] = 1;
        stk[++top] = p;
        low[p] = dfn[p];
        for (int i = h[p]; i; i = fr[i])
        {
            if (!dfn[ to[i] ])
            {
                tarjan ( to[i] );
                low[p] = min (low[p], low[ to[i] ]);
            }
            else if (ins[ to[i] ])
                low[p] = min (low[p], dfn[ to[i] ]);
        }
        if (low[p] == dfn[p])
        {
            bool flag = true;
            ++cocnt;
            while (flag)
            {
                if (stk[top] == p) flag = false;
                color[ stk[top] ] = cocnt;
                sumc[cocnt] += c[ stk[top] ];
                ins[ stk[top] ] = 0;
                --top;
            }
        }
    }
}g[4];
map<pair<int, int>, int> mp[3];
int n, m;
signed main ()
{
    freopen ("grape.in", "r", stdin);
    freopen ("grape.out", "w", stdout);
    read(n), read(m);
    for (int i = 1; i <= n; ++i)read (c[i]);
    for (int i = 1, x, y, z; i <= m; ++i)
    {
        read (x), read (y), read (z);
        for (int k = 1; k <= 3; ++k)
            if (k != z)
                g[k].adde (x, y), g[k].adde (y, x);
    }
    for (int k = 1; k <= 3; ++k)
        for (int i = 1; i <= n; ++i)
            if (!g[k].dfn[i])
                g[k].tarjan (i);
    for (int i=1; i <= n; ++i)
    {
        int idx = g[1].color[i], idy = g[2].color[i], idz = g[3].color[i];
        mp[0][ make_pair (idx, idy) ] += c[i];
        mp[1][ make_pair (idy, idz) ] += c[i];
        mp[2][ make_pair (idx, idz) ] += c[i];
    }
    for (int i = 1; i <= n; ++i)
    {
        int idx = g[1].color[i], idy = g[2].color[i], idz = g[3].color[i];
        g[1].ans[idx]=max(g[1].ans[idx],g[1].sumc[idx]+g[2].sumc[idy]-mp[0][make_pair(idx,idy)]);
        g[1].ans[idx]=max(g[1].ans[idx],g[1].sumc[idx]+g[3].sumc[idz]-mp[2][make_pair(idx,idz)]);
        g[2].ans[idy]=max(g[2].ans[idy],g[2].sumc[idy]+g[1].sumc[idx]-mp[0][make_pair(idx,idy)]);
        g[2].ans[idy]=max(g[2].ans[idy],g[2].sumc[idy]+g[3].sumc[idz]-mp[1][make_pair(idy,idz)]);
        g[3].ans[idz]=max(g[3].ans[idz],g[3].sumc[idz]+g[1].sumc[idx]-mp[2][make_pair(idx,idz)]);
        g[3].ans[idz]=max(g[3].ans[idz],g[3].sumc[idz]+g[2].sumc[idy]-mp[1][make_pair(idy,idz)]);
    }
    int q;
    read (q);
    for (int i = 1; i <= q; ++i)
    {
        int tmp; read (tmp);
        int idx = g[1].color[tmp], idy = g[2].color[tmp], idz = g[3].color[tmp];
        printf ("%lld\n", max (g[1].ans[ idx ], max (g[2].ans[ idy ], g[3].ans[ idz ])));
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/wzxbeliever/p/11608359.html