F - Breakdown

F - Breakdown

Problem Statement

You are given a simple undirected graph consisting of N vertices and M edges. For i=1,2,,M, the i-th edge connects vertices ui and vi. Also, for i=1,2,,N, vertex i is assigned a positive integer Wi, and there are Ai pieces placed on it.

As long as there are pieces on the graph, repeat the following operation:

  • First, choose and remove one piece from the graph, and let x be the vertex on which the piece was placed.
  • Choose a (possibly empty) set S of vertices adjacent to x such that ySWy<Wx, and place one piece on each vertex in S.

Print the maximum number of times the operation can be performed.

It can be proved that, regardless of how the operation is performed, there will be no pieces on the graph after a finite number of iterations.

Constraints

  • All input values are integers.
  • 2N5000
  • 1Mmin{N(N1)/2,5000}
  • 1ui,viN
  • uivi
  • ij{ui,vi}{uj,vj}
  • 1Wi5000
  • 0Ai109

Input

The input is given from Standard Input in the following format:

N M
u1 v1
u2 v2

uM vM
W1 W2 WN
A1 A2 AN

Output

Print the answer.


Sample Input 1

6 6
1 2
2 3
3 1
3 4
1 5
5 6
9 2 3 1 4 4
1 0 0 0 0 1

Sample Output 1

5

In the following explanation, let A=(A1,A2,,AN) represent the numbers of pieces on the vertices. Initially, A=(1,0,0,0,0,1).

Consider performing the operation as follows:

  • Remove one piece from vertex 1 and place one piece each on vertices 2 and 3. Now, A=(0,1,1,0,0,1).
  • Remove one piece from vertex 2. Now, A=(0,0,1,0,0,1).
  • Remove one piece from vertex 6. Now, A=(0,0,1,0,0,0).
  • Remove one piece from vertex 3 and place one piece on vertex 2. Now, A=(0,1,0,0,0,0).
  • Remove one piece from vertex 2. Now, A=(0,0,0,0,0,0).

In this procedure, the operation is performed five times, which is the maximum possible number of times.


Sample Input 2

2 1
1 2
1 2
0 0

Sample Output 2

0

In this sample input, there are no pieces on the graph from the beginning.


Sample Input 3

10 20
4 8
1 10
1 7
5 9
9 10
8 10
7 5
1 4
7 3
8 7
2 8
5 8
4 2
5 1
7 2
8 3
3 4
8 9
7 10
2 3
25 5 1 1 16 5 98 3 21 1
35 39 32 11 35 37 14 29 36 1

Sample Output 3

1380

 

解题思路

  假设现在已经知道每个节点 u 上仅有一个棋子时能执行的最大操作次数 fu,那么答案就是 u=1nfuau。由于每次只能往比自身权值小的相邻节点放置一个棋子,因此状态转移是没有环的,可以用 dp 求出每个 fu

  关于 fu 的最大值,相当于从所有权值小于 wu 的相邻节点中,选出总权值不超过 wu1 的具有最大操作次数的点集,这就是 01 背包的定义。用 fu(i,j) 表示前 i 个权值不超过 wu1 的相邻节点中,总权值不超过 j 的所有点集中操作次数的最大值,状态转移方就是 fu(i,j)=max{fu(i1,j),fu(i1,jwv)+fv(sv,wv1)}sv 表示 v 的相邻节点里面权值小于 wv 的节点数量。因此 fu(su,wu1) 就是最后要求的最大操作次数。

  最后还需要与 01 背包一样优化掉第一维,防止爆空间。初始时令 fu(j)=1,j[0,wu1]

  AC 代码如下,时间复杂度为 O(mW)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 5010, M = N * 2;

int h[N], e[M], ne[M], idx;
int w[N], a[N];
int f[N][N];

void add(int u, int v) {
    e[idx] = v, ne[idx] = h[u], h[u] = idx++;
}

int dfs(int u, int p) {
    if (f[u][w[u] - 1]) return f[u][w[u] - 1];
    for (int i = 0; i < w[u]; i++) {
        f[u][i] = 1;
    }
    for (int i = h[u]; i != -1; i = ne[i]) {
        if (e[i] != p) {
            for (int j = w[u] - 1; j >= w[e[i]]; j--) {
                f[u][j] = max(f[u][j], f[u][j - w[e[i]]] + dfs(e[i], u));
            }
        }
    }
    return f[u][w[u] - 1];
}

int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    memset(h, -1, sizeof(h));
    while (m--) {
        int u, v;
        scanf("%d %d", &u, &v);
        add(u, v), add(v, u);
    }
    for (int i = 1; i <= n; i++) {
        scanf("%d", w + i);
    }
    for (int i = 1; i <= n; i++) {
        scanf("%d", a + i);
    }
    LL ret = 0;
    for (int i = 1; i <= n; i++) {
        ret += 1ll * dfs(i, -1) * a[i];
    }
    printf("%lld", ret);
    
    return 0;
}

 

参考资料

  Editorial - Toyota Programming Contest 2024#2(AtCoder Beginner Contest 341):https://atcoder.jp/contests/abc341/editorial/9337

posted @   onlyblues  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2023-02-18 D. Triangle Coloring
2023-02-18 约数之和
2022-02-18 地宫取宝
Web Analytics
点击右上角即可分享
微信分享提示