UVA-1220-Party at Hali-Bula

题意:

一个公司员工要举行聚会,要求任意一个人不能和他的直接上司同时到场,一个员工只有一个支系上司,现在求最多有多少人到场,并且方案是否唯一(紫书282页)

分析:

紫薯写的很清楚,而且也很基础,就不重复了,只做几点记录和总结

  • 输入中输入的是名字,每个名字要和一个id对应,当然最容易想到的就是map。但是还需要注意一点,就是不能保证输入的顺序,也就是说如果首先输入的父节点之前没有出现过,那么就没办法获取到父节点的id。建树时要考虑输入数据的顺序(或者是重复输入的)
  • 关于此题,因为要判断唯一性,所以不是单纯的树的最大独立点集问题。而新增的数组f,则可以很方便的把唯一性的状态储存下来。
#define maxn 210
vector<int> v[maxn];
map<string,int> M;
int n;
int ans,res;
int dp[maxn][2],f[maxn][2];
void dfs(int u)
{
dp[u][0] = 0;
dp[u][1] = 1;
f[u][0] = f[u][1] = 1;
int l = v[u].size();
//树形dp基本框架
for(int i=0;i<l;i++)
{
int y = v[u][i];
dfs(y);
dp[u][1] += dp[y][0];
if(f[y][0]==0)f[u][1] = 0; dp[u][0] += max(dp[y][0],dp[y][1]);
if(dp[y][0]==dp[y][1])f[u][0] = 0;
else if(dp[y][0]>dp[y][1]&&f[y][0]==0)f[u][0] = 0;
else if(dp[y][0]<dp[y][1]&&f[y][1]==0)f[u][0] = 0;
}
}
//获取对应id
int cnt;
int id(const string& str)
{
if(!M.count(str))
M[str] = ++cnt;
return M[str];
}
int main()
{
while(cin>>n)
{
if(n==0)break;
for(int i=1;i<=n;i++)
v[i].clear();
//ans储存人数,res保存是否唯一
ans = 0;res = 1;
M.clear();
cnt = 0;
string a,b;
cin>>a;
id(a);
//输入的坑点就在这里
for(int i=2;i<=n;i++)
{
cin>>a>>b;
v[id(b)].push_back(id(a));
//M[a] = i;这是之前错误的写法,因为我们不能保证M[b]一定存在。
//v[M[b]].push_back(M[a]);
}
dfs(1);
ans = max(dp[1][0],dp[1][1]);
if(dp[1][0]==dp[1][1]||(dp[1][0]>dp[1][1]&&f[1][0]==0)||(dp[1][0]<dp[1][1]&&f[1][1]==0))
res = 0;
printf("%d %s\n",ans,res==0?"No":"Yes");
}
return 0;
}

UVA-1218-Perfect Service

题意:

有n个机器组成的树形结构,要求一台服务器必须连接一台电脑,求使用的最少的服务器

分析

对于任意一个机器u,可以是服务器也可以不是服务器,由于有“不是服务器的机器必须恰好与一个服务器相邻”的条件,又由于它是一棵树,所以我们借用每个节点的父节点,来表示状态。即分为三种情况

  • u是服务器。那么与u管联的任何机器可以是服务器也可以不是
  • u不是服务器,u的父节点是服务器。那么u的所有子节点都不是服务器
  • u不是服务器,u的父节点不是服务器。那么u必须恰好有一个子节点是服务器

动态转移:

d[u][0] = sum{ min(d[v][0],d[v][1])}

d[u][1] = sum{d[v][2]}

d[u][2] = min(d[u][1]-d[v][2]+d[v][0])

第三个含义是这样的:因为要求v是服务器的情况的最小值,并且u的其他子节点都不是服务器。d[u][0]保存了u子节点都不是服务器的最优解,d[v][2]保存了v不是服务器的最优解,d[v][0]保存了v是服务器的最优解。所以有上述式子可得d[u][2]的最优解

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3fffffff
#define maxn 10010
vector<int> v[maxn];
int n,ans;
int d[maxn][3];
void dp(int x,int p)
{
d[x][0] = 1;
d[x][1] = 0;
d[x][2] = maxn;
int l = v[x].size();
for(int i=0;i<l;i++)
{
int y = v[x][i];
if(y==p)continue;
dp(y,x);
d[x][0] += min(d[y][0],d[y][1]);
d[x][1] += d[y][2];
}
//因为计算d[x][2]要用到d[x][1],而d[x][1]是累加计算,所以要分开两次遍历
for(int i=0;i<l;i++)
{
int y = v[x][i];
if(y==p)continue;
d[x][2] = min(d[x][2],d[x][1]-d[y][2]+d[y][0]);
}
}
int main()
{
while(~scanf("%d",&n)&&n!=-1)
{
if(n==0)continue;
for(int i=1;i<=n;i++)
v[i].clear();
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
dp(1,0);
//最后这里的坑点,想一想为什么没有d[1][1]呢?
ans = min(d[1][0],d[1][2]);
cout<<ans<<endl;
}
return 0;
}

UVA-1220-Party at Hali-Bula && UVA-1218-Perfect Service(树形DP)的更多相关文章

  1. UVA - 1218 Perfect Service(树形dp)

    题目链接:id=36043">UVA - 1218 Perfect Service 题意 有n台电脑.互相以无根树的方式连接,现要将当中一部分电脑作为server,且要求每台电脑必须连 ...

  2. UVA - 1218 Perfect Service (树形dp)(inf相加溢出)

    题目链接 题意:给你一个树形图,让你把其中若干个结点染成黑色,其余的染成白色,使得任意一个白色结点都恰好与一个黑色结点相邻. 解法比较容易,和树上的最大独立集类似,取一个结点作为树根,对每个结点分三种 ...

  3. UVa 1218 - Perfect Service

    /*---UVa 1218 - Perfect Service ---首先对状态进行划分: ---dp[u][0]:u是服务器,则u的子节点可以是也可以不是服务器 ---dp[u][1]:u不是服务器 ...

  4. UVa 1218 - Perfect Service(树形DP)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  5. UVA - 1218 Perfect Service (树形DP)

    思路:dp[i][0]表示i是服务器:dp[i][1]表示i不是服务器,但它的父节点是服务器:dp[i][2]表示i和他的父亲都不是服务器.       转移方程: d[u][0] += min(d[ ...

  6. UVa 1218 Perfect Service 完美的服务

    ***状态设计值得一看dp[u][0]表示u是服务器(以下v均指任意u的子结点,son指u的所有子结点)ap[u][0]=sum{dp[v][1]}+1//错误,服务器是可以和其他服务器相邻的dp[u ...

  7. POJ 3342 Party at Hali-Bula / HDU 2412 Party at Hali-Bula / UVAlive 3794 Party at Hali-Bula / UVA 1220 Party at Hali-Bula(树型动态规划)

    POJ 3342 Party at Hali-Bula / HDU 2412 Party at Hali-Bula / UVAlive 3794 Party at Hali-Bula / UVA 12 ...

  8. uva 1220

    1220 - Party at Hali-Bula Time limit: 3.000 seconds Dear Contestant, I'm going to have a party at my ...

  9. UVa 10859 - Placing Lampposts 树形DP 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  10. UVA - 11584 划分字符串的回文串子串; 简单dp

    /** 链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34398 UVA - 11584 划分字符串的回文串子串: 简单 ...

随机推荐

  1. 如何找出nginx配置文件的所在位置?

    对于一台陌生的服务器或安装太久忘了位置,怎么才能简单快速的找到配置文件的位置呢?要找出配置文件的位置,需要先找出nginx可执行文件的路径 , 这里有几种方法: 1.如果程序在运行中 ps -ef | ...

  2. 计算机网络自顶向下方法第2章-应用层(application-layer).1

    2.1 应用层协议原理 2.1.1网络应用程序体系结构 1)在客户-服务器体系结构 (client-server architecture)中,有一个总是打开的主机称为服务器,它服务于来自许多其他称为 ...

  3. laravel配合swoole使用总结

    最近对接硬件做了两个项目,用到了swoole 第一个是门禁系统,需要远程开门.离线报警.定时开门.离线刷卡等功能 1.远程开门: 目前用cli创建个临时客户端连接服务端发送命令,服务端处理完成后客户端 ...

  4. 解决XP“不是有效Win32程序” 不是改Platform toolset

    背景 最近在写一个窗口程序,想在Windows XP上也能跑.先用vs 2015的App Wizard生成了一个实例窗口程序,按照网上大部分攻略,将 "Properties - Genera ...

  5. Codeforces 1143B(思维、技巧)

    自己水平太低,不丢人. 结论是最后选取的数后缀一定是若干个9,暴举即可.然而暴举也有暴举的艺术. ll n; ll dfs(ll n) { if (n == 0) return 1; if (n &l ...

  6. Codeforces 526F Pudding Monsters

    先把题目抽象一下: 有一个静态的数组,求有多少个区间[i,j]满足:j-i==max{ai,...,aj}-min{ai,...,aj} 也就是要求max-min+i-j==0的区间数 所以肿么做呢? ...

  7. bzoj2740 串 && bzoj2176 strange string(最小表示法模板)

    https://konnyakuxzy.github.io/BZPRO/JudgeOnline/2740.html 题解讲的很清楚了 (好像等于的情况应该归入case2而不是case1?并不确定) 具 ...

  8. c/c++学习系列之putchar、getchar、puts、gets的运用

    如果您只想取得使用者输入的字元,則可以使用getchar(),它直接取得使用者輸入的字元并传回,如果只想要输出一個字元,則也可以直接使用putchar(),以下是个简单的例子: #include &l ...

  9. Unity小知识记录

    //判断运行的平台 Application.platform == RuntimePlatform.Android EditorPrefs 编辑器储存数据 [AddComponentMenu(&quo ...

  10. Java 过滤器实现(登录) + 拦截器(两种方法)

    以下是实现未登录不能进入页面的实现 使用了thyemeleaf+SpringBoot+过滤器实现的,过滤器的核心代码如下: @Component @WebFilter(filterName = &qu ...