HDU1520——Anniversary Party
题意:
学校举办一个party,并且已经对每一位教职工评估了conviviality rating,规定在party中,有直接上下级关系的教职工不会同时参加。对于给定的conviviality rating和上下级关系,请问邀请哪些人参加将会使整个party的氛围最high!
分析:
dp[u][0]表示教职工u不参加party,dp[u][1]则表示参加。v为u的直接下级。
dp[u][0] += max(dp[v][0],dp[v][1])
dp[u][1] += dp[v][0]
//Date: 2015.04.20
//Time: 109ms
//Memory: 1748k
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=6001;
class Edge{
public:
int vertex;
int next;
}edges[maxn];
int n,edge_num,max_rating;
int rating[maxn];
int head[maxn];
int dp[maxn][2];
void DFS(int u){
int i,v;
dp[u][0]=0;dp[u][1]=rating[u];
for(i=head[u];i!=-1;i=edges[i].next){
v=edges[i].vertex;
if(dp[v][0]==-1)
DFS(v);
dp[u][0] += max(dp[v][0],dp[v][1]);
dp[u][1] += dp[v][0];
}
max_rating=max(max_rating,dp[u][0]);
max_rating=max(max_rating,dp[u][1]);
}
int main(){
int i,u,v;
while(scanf("%d",&n)!=EOF){
for(i=1;i<=n;i++)
scanf("%d",&rating[i]);
memset(head,-1,sizeof(head));
edge_num=0;
while(1){
scanf("%d%d",&v,&u);
if(u+v==0) break;
edges[edge_num].vertex=v;
edges[edge_num].next=head[u];
head[u]=edge_num++;
}
max_rating=-800000;
memset(dp,-1,sizeof(dp));
for(i=1;i<=n;i++){
if(dp[i][0]==-1)
DFS(i);
}
printf("%d\n",max_rating);
}
return 0;
}
POJ1655——Balancing Act
题意:求树的重心
分析:
max_branch[u]表示以u为根的子树中的最大分支的节点数,sum[u]表示以u为根的子树的总节点数。
在对树进行DFS的过程中动态求解,v为u的子节点
max_branch[u]=max(max_branch[u],sum[v])
sum[u] += sum[v]
//Date: 2015.04.20
//Time: 47ms
//Memory: 704k
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=20005;
class Edge{
public:
int vertex;
int next;
}edges[maxn<<1];
int n,edge_num,number,balance;
int head[maxn];
int sum[maxn];
int max_branch[maxn];
void DFS(int u,int p){
int i,v;
sum[u]=1;max_branch[u]=0;
for(i=head[u];~i;i=edges[i].next){
v=edges[i].vertex;
if(v!=p){
DFS(v,u);
max_branch[u]=max(max_branch[u],sum[v]);
sum[u] += sum[v];
}
}
max_branch[u]=max(max_branch[u],n-sum[u]);
if(balance==max_branch[u] && number>u)
number=u;
if(balance>max_branch[u]){
balance=max_branch[u];
number=u;
}
}
inline void addEdge(int u,int v){
edges[edge_num].vertex=v;
edges[edge_num].next=head[u];
head[u]=edge_num++;
}
int main(){
int test,j,u,v;
scanf("%d",&test);
while(test--){
scanf("%d",&n);
memset(head,-1,sizeof(head));
edge_num=0;
for(j=1;j<n;j++){
scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
}
number=n+1;balance=n;
DFS(1,0);
printf("%d %d\n",number,balance);
}
return 0;
}<br abp="639" />