点線ガバナンスの実践

P3806 [テンプレート]パーティション1点

トピックリンク

問題解決のアイデア:

パーティションポイントは、各ノードのプロセスからのルートに分割点の... ..大きな複雑各質問に対する直接I感触を算出する、
ポインターの左右の動きは、長さkのパスの数をソートした後に計算されます

#include <bits/stdc++.h>
using namespace std;
/*    freopen("k.in", "r", stdin);
    freopen("k.out", "w", stdout); */
// clock_t c1 = clock();
// std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e5 + 7;
const ll MAXM = 1e6 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
struct Edge
{
    int u, v, val, net;
} e[MAXN << 1];
int cnt = -1;
int head[MAXN];
int n, m, sum;
int k;
void add(int u, int v, int val)
{
    e[++cnt].u = u;
    e[cnt].v = v;
    e[cnt].val = val;
    e[cnt].net = head[u];
    head[u] = cnt;
}
int mx[MAXN], vis[MAXN], sz[MAXN];
int rt;
int ans;
void dfs(int now, int fa)
{
    sz[now] = 1, mx[now] = 0;
    for (int i = head[now]; ~i; i = e[i].net)
    {
        int v = e[i].v;
        if (vis[v] || v == fa)
            continue;
        dfs(v, now);
        sz[now] += sz[v];
        mx[now] = max(mx[now], sz[v]);
    }
    mx[now] = max(mx[now], sum - sz[now]);
    if (mx[now] < mx[rt])
        rt = now;
}
int tot;
int dis[MAXN];
void getdis(int now, int fa, int len)
{
    for (int i = head[now]; ~i; i = e[i].net)
    {
        int v = e[i].v;
        if (vis[v] || v == fa)
            continue;
        dis[++tot] = len + e[i].val;
        getdis(v, now, dis[tot]);
    }
}
int solve(int now, int len)
{
    int ret = 0;
    dis[tot = 1] = len;
    getdis(now, -1, len);
    int l = 1, r = tot;
    sort(dis + 1, dis + 1 + tot);
    while (l < r)
    {
        if (dis[l] + dis[r] == k)
        {
            l++, r--;
            ret++;
        }
        else if (dis[l] + dis[r] < k)
            l++;
        else
            r--;
    }
    // cout << ret << endl;
    return ret;
}
void divide(int now)
{
    vis[now] = 1;
    ans += solve(now, 0);
    for (int i = head[now]; ~i; i = e[i].net)
    {
        int v = e[i].v;
        if (vis[v])
            continue;
        ans -= solve(v, e[i].val);
        rt = 0;
        sum = sz[v];
        dfs(v, now);
        divide(rt);
    }
}
void init()
{
    memset(head, -1, sizeof(head));
    cnt = -1;
    rt = 0;
    mx[0] = inf;
}
int main()
{
    scanf("%d%d", &n, &m);
    init();
    for (int i = 0; i < n - 1; i++)
    {
        int u, v, val;
        scanf("%d%d%d", &u, &v, &val);
        add(u, v, val);
        add(v, u, val);
    }
    for (int i = 0; i < m; i++)
    {
        scanf("%d", &k);
        memset(vis, 0, sizeof(vis));
        ans = 0;
        rt = 0;
        sum = n;
        dfs(1, -1);
        divide(rt);
        printf("%s\n", ans ? "AYE" : "NAY");
    }
    return 0;
}

P2634 [ナショナルチーム]コングコングココア

コングコングココア

問題解決のアイデア:

変更は、機能コードに問題を解決する答え0,1,2寄与のパスのルートの経路長に金型3の後、ほぼ同じである\(DIS [0] * DIS [0] + 2 * DIS [ 1] * DIS [2] \ )

#include <bits/stdc++.h>
using namespace std;
/*    freopen("k.in", "r", stdin);
    freopen("k.out", "w", stdout); */
// clock_t c1 = clock();
// std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 2e5 + 7;
const ll MAXM = 1e6 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
struct Edge
{
    int u, v, val, net;
} e[MAXN << 1];
int cnt = -1;
int head[MAXN];
int n;
int sum;
void add(int u, int v, int val)
{
    e[++cnt].u = u;
    e[cnt].v = v;
    e[cnt].val = val;
    e[cnt].net = head[u];
    head[u] = cnt;
}
int mx[MAXN], vis[MAXN], sz[MAXN];
int rt;
ll ans;
void dfs(int now, int fa)
{
    sz[now] = 1, mx[now] = 0;
    for (int i = head[now]; ~i; i = e[i].net)
    {
        int v = e[i].v;
        if (vis[v] || v == fa)
            continue;
        dfs(v, now);
        sz[now] += sz[v];
        mx[now] = max(mx[now], sz[v]);
    }
    mx[now] = max(mx[now], sum - sz[now]);
    if (mx[now] < mx[rt])
        rt = now;
}
ll dis[4];
void getdis(int now, int fa, int len)
{
    for (int i = head[now]; ~i; i = e[i].net)
    {
        int v = e[i].v;
        if (vis[v] || v == fa)
            continue;
        dis[(len + e[i].val) % 3]++;
        getdis(v, now, len + e[i].val);
    }
}
ll solve(int now, int len)
{
    dis[0] = dis[1] = dis[2] = 0;
    dis[len % 3]++;
    getdis(now, -1, len);
    return dis[0] * dis[0] + 2 * dis[1] * dis[2];
}
void divide(int now)
{
    vis[now] = 1;
    ans += solve(now, 0);
    for (int i = head[now]; ~i; i = e[i].net)
    {
        int v = e[i].v;
        if (vis[v])
            continue;
        ans -= solve(v, e[i].val);
        rt = 0;
        sum = sz[v];
        dfs(v, now);
        divide(rt);
    }
}
void init()
{
    memset(vis, 0, sizeof(vis));
    memset(head, -1, sizeof(head));
    cnt = -1;
    rt = 0;
    mx[0] = inf;
}
ll GCD(ll a, ll b) { return b == 0 ? a : GCD(b, a % b); }
int main()
{
    scanf("%d", &n);
    init();
    for (int i = 0; i < n - 1; i++)
    {
        int u, v, val;
        scanf("%d%d%d", &u, &v, &val);
        val %= 3;
        add(u, v, val);
        add(v, u, val);
    }
    sum = n;
    dfs(1, -1);
    divide(rt);
    ll div = GCD(ans, 1LL * n * n);
    printf("%lld/%lld\n", ans / div, 1LL * n * n / div);
    // system("pause");
    return 0;
}

おすすめ

転載: www.cnblogs.com/graytido/p/11872481.html