문제풀이 보고서
11718 단어 동적 기획
The first line of each block contains an integer N (1 < N <= 1000). The second line contains N numbers separated by one or more blanks. The I-th number means W(I) (0 < W(I) <= 10000). The third line contains N numbers separated by one or more blanks. The I-th number means D(I) (0 <= D(I) <= 10000). The following N-1 lines each contains three integers u, v, L (1 <= u, v <= N,0 < L <= 1000), which means there is a highway between city u and v of length L. Output For each test case output the minimum cost on a single line. Sample Input 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 3 4 1 4 1 4 1 1 1 1 1 1 2 1 1 1 1 1 2 1 1 1 2 1 1 1 1 2 1 1 1 1 1 1 1 2 1 1 1 1 1 2 1 1 2 1 2 1 3 4 1 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 2 1 1 1 1 2 1 1 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 2 1 2 1 2 1 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 4 2 Sample 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3고속도로마다 길이가 다를 수 있습니다.도시 i에 대해 이 도시에서 방화소를 건설하는 비용은 w[i]이다. 그리고 반드시 d[i] 범위 내에서 하나의 역(그 자신을 포함) j를 찾아야 한다. 적어도 이런 j역이 존재하고 j역에 방화소를 건설해야 한다. 그러면 i는 j에 의존할 수 있다.우리의 목적은 이러한 네트워크를 구하는 것이다. 모든 도시가 의존하는 방화소가 있고 비용 요구가 가장 적다.
분석: 처음에 이 문제를 받으면 안개가 낀다.np의 알고리즘만 생각할 수 있습니다.나중에 진계봉의 느슨한 문제 풀이 방법을 보고 나서야 이런 유형의 문제를 대충 알 수 있었다.데이터 범위가 1000인 것을 보면 분명히 n^2의 알고리즘이다. 따라서 우리는 spfa로 임의의 두 점 사이의 거리dis[u][v]를 미리 처리한 다음에 나무의 점 분치 사상을 사용한다. 나무를 풀 때 우리는 이 나무의 뿌리 노드와 그의 아들 노드만 주목하고 이 나무의 아버지를 주목하지 않는다. 그러면 후효성 문제를 고려할 필요가 없다.그리고 우리는 상태 dp[i]를 정의할 수 있지만 이렇게 정의한 후에 분명히 옮길 수 없다. 왜냐하면 i가 어느 사이트에 의존하는지 모르기 때문이다.자주 사용하는 방법은 1차원과 dp[i][j]를 추가하는 것이다.위에서 상태는 dp[i][j]로 i를 뿌리로 하는 자수를 나타낼 수 있고 i번째 도시는 j에 의존하고 i자수 중의 다른 노드는 모두 의존하는 노드의 최소 비용을 나타낸다.이 말은 두 가지가 반드시 긴박하고 전체 해 공간의 범위를 좁히는 것이지만, 우리는 먼저 이러한 상태가 반드시 정확하다는 것을 증명해야 한다.(구체적으로 논문을 보며) 그렇다면 문제가 왔다. 옮기는 것은 어떤 것일까?관찰한 바에 의하면 i를 뿌리로 하는 자수를 계산할 때마다 1-n 노드를 매거해야 한다.만약에 우리가 폭력적으로 한다면 매번 i노드는 n을 매거해야 한다. 그의 아들은 여러 가지 결정을 내린다. 그 중 하나는 i나무 안의 노드를 의존소로 하고 다른 하나는 i나무 이외의 노드를 의존소로 한다. 이것은np의 복잡도이다.이것을 생각하니 나는 문제가 다시 원래의 곳으로 돌아간 것을 발견하였다.Orz 자세히 분석해 보자. 매번 뿌리 노드 i에 대한 의존역 v를 매거할 때마다 i역은 반드시 방화소를 건설했다. 그의 자금은 이미 썼다. 만약에 i의 아들 노드가 v를 의존역으로 할 수 있다면 v를 의존역으로 하는 것보다 더 좋은 상황은 없다. 만약에 i의 아들 노드가 v를 의존역으로 할 수 없다면 i의 아들은 반드시 그를 뿌리로 하는 자수 나무의 노드를 의존역으로 삼을 것이다.따라서 보조 dp수 그룹best[i]를 설계하여 i를 뿌리로 하는 나무를 표시하면 제목의 요구를 충족시키는 최소한의 비용이 든다.이렇게 설정하면 몇 가지 조건을 제한하고 공간을 이해하는 범위를 좁혀서 우리는 n^2의 속도 내에서 해답을 구할 수 있다.마지막에 옮겨서 자연스럽게 나왔어요.dp[u][j] = w[j] + sigma( min(dp[v][j] - w[j], best[v]); best[u] = min(best[i], dp[u][j]);
//
// Created by Running Photon on 2015-09-07
// Copyright (c) 2015 Running Photon. All rights reserved.
//
//
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ALL(x) x.begin(), x.end()
#define INS(x) inserter(x, x,begin())
#define ll long long
#define CLR(x) memset(x, 0, sizeof x)
#define MAXN 9999
#define MAXSIZE 10
#define DLEN 4
using namespace std;
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1e4 + 10;
const int maxv = 1e3 + 10;
const double eps = 1e-9;
inline int read() {
char c = getchar();
int f = 1;
while(!isdigit(c)) {
if(c == '-') f = -1;
c = getchar();
}
int x = 0;
while(isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
int w[maxv], d[maxv];
int head[maxv], nxt[maxn], pnt[maxn], cost[maxn], cnt;
int dp[maxv][maxv], dis[maxv][maxv], best[maxv];
int n;
void add_edge(int u, int v, int val) {
cost[cnt] = val;
pnt[cnt] = v;
nxt[cnt] = head[u];
head[u] = cnt++;
}
int vis[maxv];
void spfa(int root) {
for(int i = 1; i <= n; i++) {
dis[root][i] = inf;
}
dis[root][root] = 0;
queue <int> que;
que.push(root);
vis[root] = 1;
while(que.size()) {
int u = que.front();
que.pop();
vis[u] = 0;
for(int i = head[u]; ~i; i = nxt[i]) {
int v = pnt[i];
if(dis[root][v] > dis[root][u] + cost[i]) {
dis[root][v] = dis[root][u] + cost[i];
if(!vis[v]) {
vis[v] = 1;
que.push(v);
}
}
}
}
}
void dfs(int u, int fa) {
for(int i = head[u]; ~i; i = nxt[i]) {
int v = pnt[i];
if(v == fa) continue;
dfs(v, u);
}
for(int i = 1; i <= n; i++) {
if(dis[u][i] <= d[u]) {
dp[u][i] = w[i];
for(int j = head[u]; ~j; j = nxt[j]) {
int v = pnt[j];
if(v == fa) continue;
dp[u][i] += min(dp[v][i] - w[i], best[v]);
}
best[u] = min(best[u], dp[u][i]);
}
}
}
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
int cas = read();
while(cas--) {
CLR(vis); memset(best, 0x3f, sizeof best);
cnt = 0; memset(head, -1, sizeof head);
memset(dp, 0x3f, sizeof dp);
n = read();
for(int i = 1; i <= n; i++)
w[i] = read();
for(int i = 1; i <= n; i++)
d[i] = read();
for(int i = 1; i < n; i++) {
int u = read(), v = read(), val = read();
add_edge(u, v, val);
add_edge(v, u, val);
}
for(int i = 1; i <= n; i++)
spfa(i);
CLR(vis);
dfs(1, 1);
printf("%d
", best[1]);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
01 가방, 완전 가방, 다중 가방 dp(동적 기획 입문 dp)01 가방은 2진법으로 직접 표시할 수 있지만 데이터 양이 너무 많으면 시간을 초과하는 것이 폭력이다.01 가방의 사상은 바로 이 물품에 대해 내가 넣은 가치가 큰지 안 넣은 가치가 큰지 비교하여 방정식 f[i][v...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.