BZOJ 2427 HAOI 2010 소프트웨어 설치 Tarjan + 트리 DP
사고방식: 한 고리에 나타난 점은 모두 선택하든지 아니면 모두 선택하지 않든지 간에 먼저 점을 줄이고 그 다음에 나무가 되어 나무에 배낭을 만들면 된다.
CODE:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 2010
using namespace std;
int head[MAX],total;
int next[MAX],aim[MAX];
inline void Add(int x,int y)
{
next[++total] = head[x];
aim[total] = y;
head[x] = total;
}
int cost[MAX],val[MAX];
int father[MAX];
int cnt,all;
int dfn[MAX],low[MAX],_clock;
int stack[MAX],top;
bool in_stack[MAX];
int changed[MAX],scc;
void Tarjan(int x)
{
dfn[x] = low[x] = ++_clock;
stack[++top] = x;
in_stack[x] = true;
for(int i = head[x]; i; i = next[i]) {
if(!dfn[aim[i]])
Tarjan(aim[i]),low[x] = min(low[x],low[aim[i]]);
else if(in_stack[aim[i]])
low[x] = min(low[x],dfn[aim[i]]);
}
if(dfn[x] == low[x]) {
scc++;
int temp;
do {
temp = stack[top--];
in_stack[temp] = false;
changed[temp] = scc;
}while(temp != x);
}
}
struct Graph{
int head[MAX],total;
int next[MAX],aim[MAX];
int _in[MAX],f[MAX][MAX];
int cost[MAX],val[MAX];
void Add(int x,int y) {
next[++total] = head[x];
aim[total] = y;
head[x] = total;
++_in[y];
}
void DP(int x) {
for(int i = head[x]; i; i = next[i]) {
DP(aim[i]);
for(int j = all - cost[x]; j >= 0; --j)
for(int k = 0; k <= j; ++k)
f[x][j] = max(f[x][j],f[x][k] + f[aim[i]][j - k]);
}
for(int i = all; i; --i) {
if(i >= cost[x]) f[x][i] = f[x][i - cost[x]] + val[x];
else f[x][i] = 0;
}
}
int GetAns() {
memset(f,0,sizeof(f));
int S = 0;
for(int i = 1; i <= scc; ++i)
if(!_in[i])
Add(S,i);
DP(S);
return f[S][all];
}
}graph;
int main()
{
cin >> cnt >> all;
for(int i = 1; i <= cnt; ++i)
scanf("%d",&cost[i]);
for(int i = 1; i <= cnt; ++i)
scanf("%d",&val[i]);
for(int x,i = 1;i <= cnt; ++i) {
scanf("%d",&x);
if(x) Add(x,i);
}
for(int i = 1; i <= cnt; ++i)
if(!dfn[i]) Tarjan(i);
for(int x = 1; x <= cnt; ++x)
for(int i = head[x]; i; i = next[i])
if(changed[x] != changed[aim[i]])
graph.Add(changed[x],changed[aim[i]]);
for(int i = 1; i <= cnt; ++i) {
graph.cost[changed[i]] += cost[i];
graph.val[changed[i]] += val[i];
}
cout << graph.GetAns() << endl;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.