如果知道了树的形态,那么可以树形DP,每个时刻只需要计算必选根的独立集个数以及必不选根的独立集个数。

那么现在知道独立集个数,要构造出树,可以考虑DP这棵树的形态,然后将之前树形DP的值作为现在DP的状态,即$dp[i][j]$表示必选根的独立集个数为$i$,必不选根的独立集个数为$j$时,树的节点数最少是多少。

那么完成这个DP之后,输出方案只需要沿着最优值来的顺序dfs输出即可。

#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<time.h>
#include<assert.h>
#include<iostream>
using namespace std;
typedef long long LL;
typedef pair<int,int>pi;
const int Inf=100;
int cnt;
int dp[2020][2020];
struct Node{
short i,j,x,y;
Node(){}
Node(short i,short j,short x,short y):i(i),j(j),x(x),y(y){}
};
Node pre[2020][2020];
void dfs(int u,int x,int y){
if(x==1&&y==1)return ;
//printf("x=%d y=%d\n",x,y);
dfs(u,pre[x][y].i,pre[x][y].j);
++cnt;
printf("%d %d\n",u,cnt);
dfs(cnt,pre[x][y].x,pre[x][y].y);
}
vector<int>V[3000];
int main(){
int tl=0;
for(int i=1;i<=2005;i++){
for(int j=i;j<=2005;j+=i)V[j].push_back(i);
}
for(int i=0;i<2020;i++)for(int j=0;j<2020;j++)dp[i][j]=Inf;
dp[1][1]=1;
for(int i=1;i<=2005;i++){
for(int j=1;j<=2005;j++){
if(dp[i][j]>15)continue;
for(int y=1;y*i<=2005;y++){
for(int x=1;(x+y)*j<=2005;x++){
int tmp=dp[i][j]+dp[x][y];
int nx=y*i,ny=j*(x+y);
if(dp[nx][ny]>tmp){
dp[nx][ny]=tmp;
pre[nx][ny]=Node(i,j,x,y);
}
tl++;
}
}
for(int y=1;y*(i+j)<=2005;y++){
for(int x=1;x*j<=2005;x++){
int tmp=dp[i][j]+dp[x][y];
int nx=j*x,ny=y*(i+j);
if(dp[nx][ny]>tmp){
dp[nx][ny]=tmp;
pre[nx][ny]=Node(x,y,i,j);
}
tl++;
}
} }
}
/*
for(int nx=1;nx<=2005;nx++){
for(int ny=1;ny<=2005;ny++){
if(nx==1&&ny==1){dp[nx][ny]=1;continue;}
for(int it1=0;it1<V[nx].size();it1++){
for(int it2=0;it2<V[ny].size();it2++){
int i=V[nx][it1],j=V[ny][it2];
int y=nx/i,x=ny/j-y;
if(x>=1&&y>=1&&dp[i][j]+dp[x][y]<dp[nx][ny]){
dp[nx][ny]=dp[i][j]+dp[x][y];
pre[nx][ny]=Node(i,j,x,y);
}
tl++;
}
}
}
}
*/
//printf("tl=%d\n",tl);
int _;scanf("%d",&_);
while(_--){
int m;
scanf("%d",&m);
//for(int tm=1;tm<=2000;tm++){
// m=tm+1;
m++;
bool flag=0;
int sx=-1,sy;
for(int i=0;i<=m;i++){
if(dp[i][m-i]<=15){
sx=i;sy=m-i;
break;
}
}
if(sx<0)puts("-1");
else{
printf("%d\n",dp[sx][sy]);
cnt=1;
dfs(1,sx,sy);
}
}
return 0;
}

  

ZOJ3951 : Independent Set的更多相关文章

  1. 写一个程序可以对两个字符串进行测试,得知第一个字符串是否包含在第二个字符串中。如字符串”PEN”包含在字符串“INDEPENDENT”中。

    package lovo.test; import java.util.Scanner; public class Java { @param args public static void main ...

  2. Deep Learning 13_深度学习UFLDL教程:Independent Component Analysis_Exercise(斯坦福大学深度学习教程)

    前言 理论知识:UFLDL教程.Deep learning:三十三(ICA模型).Deep learning:三十九(ICA模型练习) 实验环境:win7, matlab2015b,16G内存,2T机 ...

  3. [ZZ] KlayGE 游戏引擎 之 Order Independent Transparency(OIT)

    转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2233 http://dogasshole.iteye.com/blog/1429665 ht ...

  4. Andrew Ng机器学习公开课笔记–Independent Components Analysis

    网易公开课,第15课 notes,11 参考, PCA本质是旋转找到新的基(basis),即坐标轴,并且新的基的维数大大降低 ICA也是找到新的基,但是目的是完全不一样的,而且ICA是不会降维的 对于 ...

  5. Questions that are independent of programming language. These questions are typically more abstract than other categories.

    Questions that are independent of programming language.  These questions are typically more abstract ...

  6. Interview-Largest independent set in binary tree.

    BT(binary tree), want to find the LIS(largest independent set) of the BT. LIS: if the current node i ...

  7. 【转】NDK编译可执行文件在Android L中运行显示error: only position independent executables (PIE) are supported.失败问题解决办法。

    原文网址:http://blog.csdn.net/hxdanya/article/details/39371759 由于使用了NDK编译的可执行文件在应用中调用,在4.4及之前的版本上一直没出问题. ...

  8. 基于Hama并联平台Finding a Maximal Independent Set 设计与实现算法

    笔者:白松 NPU学生. 转载请注明出处:http://blog.csdn.net/xin_jmail/article/details/32101483. 本文參加了2014年CSDN博文大赛,假设您 ...

  9. More than one file was found with OS independent path 錯誤

    More than one file was found with OS independent path 'lib/armeabi/libmrpoid.so',. 翻譯過來就是:在操作系統的獨立目錄 ...

随机推荐

  1. linux:安装并使用mongo

    1.下载mongo:  curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz 2.解压: tar -zxvf ...

  2. 四.idea本地调试hadoop程序

    目录: 目录见文章1 1.先上案例代码 WordCount.java: import java.io.IOException; import java.util.StringTokenizer; im ...

  3. node.js(一)

    安装官网: https://nodejs.org/en/ 运行代码: var http=require('http') http.createServer(function(req,res){ res ...

  4. zeromq的安装,部署(号称最快的消息队列,消息中间件)

    1:Storm作为一个实时处理的框架,产生的消息需要快速的进行处理,比如存在消息队列ZeroMQ里面. 由于消息队列ZeroMQ是C++写的,而我们的程序是运行在JVM虚拟机里面的.所以需要jzmq这 ...

  5. Ant之build.xml详解

    Ant之build.xml详解 关键字: ant build.xml Ant的概念 可能有些读者并不连接什么是Ant以及入可使用它,但只要使用通过Linux系统得读者,应该知道make这个命令.当编译 ...

  6. Codeforces 633F The Chocolate Spree 树形dp

    The Chocolate Spree 对拍拍了半天才知道哪里写错了.. dp[ i ][ j ][ k ]表示在 i 这棵子树中有 j 条链, 是否有链延伸上来. #include<bits/ ...

  7. BZOJ2142 礼物 扩展lucas 快速幂 数论

    原文链接http://www.cnblogs.com/zhouzhendong/p/8110015.html 题目传送门 - BZOJ2142 题意概括 小E购买了n件礼物,送给m个人,送给第i个人礼 ...

  8. nexus、maven私服仓库(一)

    下载地址:http://www.sonatype.com/download-oss-sonatype 将下载好的nexus解压到指定的目录下,我这里使用的是nexus-3.14.0-04-win64  ...

  9. IdentityServer4.AccessTokenValidation

    IdentityServer4.AccessTokenValidation Authentication handler for ASP.NET Core 2 that allows acceptin ...

  10. P1063 能量项链 区间dp

    题目描述 在MarsMars星球上,每个MarsMars人都随身佩带着一串能量项链.在项链上有NN颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一 ...