您的位置:首页 > 大数据 > 人工智能

树形DP——Party a Haili-Bula ( HDU 3342 )

2016-07-21 20:20 549 查看
题目链接:

http://poj.org/problem?id=3342

分析:

输入数据为字符串,需要与序号绑定,所以需要用到map容器。然后就是树形DP了。

题解:

1.MAP存储:

map<string, int> names;
map<string, int>::iterator it;

int ADD(string x)//加入字符串
{
int num;
it = names.find(x);//查询是否存在与map中
if(it == names.end())//不存在
{
num  = t;
names[x] = t++;
}
else               //存在
{
num = it->second;
}
return num;//返回字符串对应的序号
}


2.vector建树:

for(int i=0; i<n-1; i++)
{
string employee, Boss ;
cin >> employee >> Boss;
int F = ADD(Boss);//得到对应序号
int S = ADD(employee);//得到对应序号
vec[F].push_back(S);//存储每个节点的儿子
}


3.DFS搜索:

void DFS(int root)
{
for(int i=0; i<vec[root].size(); i++)//搜索每一个节点的所有儿子
{
int F=vec[root][i];
DFS(F);//继续搜这个儿子的所有儿子
//下面是DP
dp[root][0]+=max(dp[F][0],dp[F][1]);//父亲root不来,判断儿子来不来的情况
dp[root][1]+=dp[F][0];//父亲root来的情况
}
}


4.判断解是否唯一:

int flag=1;
for(int i=0; i<n; i++)
{
if(dp[i][0]>dp[i][1])//如果i不去结果更大
{
for(int j=0; j<vec[i].size(); j++)//那么遍历i的所有儿子
{
int v=vec[i][j];
if(dp[v][0]==dp[v][1])
{//如果儿子去不去结果一样,那么解不唯一,跳出
flag=0;
break;
}
}
}
if(flag==0)
break;
}

if(flag==0 || dp[0][0]==dp[0][1])//注意判断条件,
printf("%d No\n", max(dp[0][0],dp[0][1]));
else
printf("%d Yes\n", max(dp[0][0],dp[0][1]));


AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#define N 222
using namespace std;

map<string, int> names;
map<string, int>::iterator it;

int n;
int t;
int e;

int dp
[2];
vector<int> vec
;

int ADD(string x)
{
int num;
it = names.find(x);
if(it == names.end())
{
num  = t;
names[x] = t++;
}
else
{
num = it->second;
}
return num;
}

void DFS(int root)
{
for(int i=0; i<vec[root].size(); i++)
{
int F=vec[root][i];
DFS(F);
dp[root][0]+=max(dp[F][0],dp[F][1]);
dp[root][1]+=dp[F][0];
}
}

int main()
{
while(cin >> n && n)
{
names.clear();
t = 0;
e = 0;
for(int i=0; i<n; i++)
{
vec[i].clear();
dp[i][0]=0;
dp[i][1]=1;
}
string BigBoss;
cin >>BigBoss;
names[BigBoss] = t++;

for(int i=0; i<n-1; i++)
{
string employee, Boss ;
cin >> employee >> Boss;
int F = ADD(Boss);
int S = ADD(employee);
//cout << "F: "<<F << "  S: "<<S<<endl;
vec[F].push_back(S);
}

DFS(0);

int flag=1;
for(int i=0; i<n; i++)
{
if(dp[i][0]>dp[i][1])
{
for(int j=0; j<vec[i].size(); j++)
{
int v=vec[i][j];
if(dp[v][0]==dp[v][1])
{
flag=0;
break;
}
}
}
if(flag==0)
break;
}

if(flag==0 || dp[0][0]==dp[0][1])//注意判断条件,
printf("%d No\n", max(dp[0][0],dp[0][1]));
else
printf("%d Yes\n", max(dp[0][0],dp[0][1]));

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  树形DP ACM 算法 HDU-3342