Tree
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 3506   Accepted: 1204

Description

Consider a tree with N vertices, numbered from 1 to N. Add, if it is possible, a minimum number of edges thus every vertex belongs to exactly one cycle.

Input

The input has the following structure: 



x(1) y(1) 

x(2) y(2) 

... 

x(N-1) y(n-1) 

N (3 <= N <=100) is the number of vertices. x(i) and y(i) (x(i), y(i) are integers, 1 <= x(i), y(i) <= N) represent the two vertices connected by the i-th edge. 

Output

The output will contain the value -1 if the problem doesn't have a solution, otherwise an integer, representing the number of added edges.

Sample Input

7
1 2
1 3
3 5
3 4
5 6
5 7

Sample Output

2

Source


树形DP啊,可是知道也推不出公式来,。无奈的看了解题报告。发现前方的道路还非常漫长啊,这思路神了
http://www.cnblogs.com/vongang/archive/2012/08/12/2634763.html
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#define N 110
#define INF 150
using namespace std;
struct num
{
int y,next;
}a[N*N];
int b[N],Top;
int dp[N][3];
bool ch[N];
int main()
{
//freopen("data.txt","r",stdin);
void addeage(int x,int y);
void dfs(int x);
int n;
while(scanf("%d",&n)!=EOF)
{
Top = 0;
memset(b,-1,sizeof(b));
for(int i=1;i<=n-1;i++)
{
int x,y;
scanf("%d %d",&x,&y);
addeage(x,y);
addeage(y,x);
}
for(int i=1;i<=n;i++)
{
dp[i][0] = dp[i][1] = dp[i][2] = INF;
}
memset(ch,false,sizeof(ch));
dfs(1);
//cout<<dp[3][1]<<endl;
if(dp[1][0]==INF)
{
printf("%d\n",-1);
}else
{
printf("%d\n",dp[1][0]);
}
}
return 0;
}
void addeage(int x,int y)
{
a[Top].y = y;
a[Top].next = b[x];
b[x] = Top++;
}
void dfs(int x)
{
ch[x] = true;
bool uv = true;
for(int i=b[x];i!=-1;i=a[i].next)
{
int y = a[i].y;
if(!ch[y])
{
uv = false;
break;
}
}
if(uv)
{
dp[x][1] =0;
return ;
}
dp[x][1] = 0;
int sum = 0;
bool ch2[N];
memset(ch2,false,sizeof(ch2));
for(int i=b[x];i!=-1;i=a[i].next)
{
int y = a[i].y;
if(!ch[y])
{
dfs(y);
ch2[y] = true;
dp[x][1]+=dp[y][0];
sum+=dp[y][0];
}
}
if(dp[x][1]>=INF)
{
dp[x][1] = INF;
}
for(int i=b[x];i!=-1;i=a[i].next)
{
int y = a[i].y;
if(!ch2[y])
{
continue;
}
int w = sum-dp[y][0]+min(dp[y][1],dp[y][2]);
if(w>=INF)
{
w = INF;
}
dp[x][2] = min(dp[x][2],w);
w = sum-dp[y][0] + dp[y][2]+1;
if(w>=INF)
{
w = INF;
}
dp[x][0] = min(dp[x][0],w);
}
for(int i=b[x];i!=-1;i=a[i].next)
{
int y1 = a[i].y;
if(!ch2[y1])
{
continue;
}
for(int j=b[x];j!=-1;j=a[j].next)
{
int y2 = a[j].y;
if(y1==y2||!ch2[y2])
{
continue;
}
int w = sum-dp[y1][0] - dp[y2][0] + min(dp[y1][1],dp[y1][2]) + min(dp[y2][1],dp[y2][2])+1;
if(w>=INF)
{
w = INF;
}
dp[x][0] = min(dp[x][0],w);
}
}
}

最新文章

  1. Xamarin.Android-用ZXing实现二维码扫描以及连续扫描
  2. 18、(番外)匿名方法+lambda表达式
  3. Selenium2学习-027-WebUI自动化实战实例-025-JavaScript 在 Selenium 自动化中的应用实例之三(页面滚屏,模拟鼠标拖动滚动条)
  4. getbyclass
  5. RTMP协议详解(转)
  6. Centos7多网卡绑定操作,通过nmcli命令操作。
  7. SDL 2.0 如何在 windows 上使用?
  8. ANT不完全总结,包含各种命令,ant例子等,转自:http://lavasoft.blog.51cto.com/62575/87306
  9. Springboot关于脚本脚本启动的项目:
  10. LeetCode数组解题模板
  11. JavaScript中的闭包和作用域链
  12. PhotoShop常用的功能汇总
  13. php操作redis数据库方法总结
  14. Day09 (黑客成长日记) 爬虫入门
  15. QEMU Networking
  16. centos7下安装docker(26如何配置Health Check)
  17. Python 基础知识----数据类型
  18. TeeChart取消3D
  19. Java——线程同步
  20. Python 正则表达式贪婪模式

热门文章

  1. avro序列化详细操作
  2. Linux 内核参数 和 Oracle相关参数调整
  3. 两列布局(浮动、定位、flex)和三列布局(圣杯、双飞翼、flex)
  4. Linux信号(signal) 机制分析(转)
  5. Jmeter-安装及配置(一)
  6. git merge rebase的区别及应用场景
  7. UINavigationController(二)
  8. 利用python拼接图片
  9. JAVA热部署原理
  10. UML类图详解_关联关系_多对一