摘要: 先建树,以0为根,把入度为0的点都与建边。此题建单向边即可。状态方程:dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][j])方程很好想,dp的初始化和进行背包是倒是用很长的时间。 1 #include 2 #include 3 #include 4 #include 5 using namespace std; 6 const int N=205; 7 int dp[N][N]; 8 vectorV[N]; 9 int val[N];10 void init()11 {12 memset(dp,0,sizeof(dp));13 for(int i=... 阅读全文
posted @ 2013-07-12 09:59 自力创辉煌 阅读(124) 评论(0) 推荐(0)
摘要: 和poj2342一样,只是加了判断最大值是否唯一。当dp2【s】>=dp1【s】时,若dp1【x】==dp2【x】;则不唯一。因为父节点不去更优。儿子节点去和不去都一样。结果就不唯一了。特殊考虑的是根节点,如果dp1【root】==dp2【root】 ,则不唯一,因为已经到根节点,不影响其他的点了。此题还可以建单向边,因为给定的条件是老板在后面, 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 vectorV[220]; 9 mapM;10 int vis 阅读全文
posted @ 2013-07-11 18:10 自力创辉煌 阅读(115) 评论(0) 推荐(0)
摘要: 题意是:给定n个点,n-1条有向边。求 使该点到所有点改变边方向最少,并输出那些点。题解:正向边权值为0,反向为1.第一次dfs记录每个点到所有子树中需要改变的边的条数。 (自下向上推)(优化下只需求出根节点到所有的点需要改变的边的条数)第二次dfs由父节点求子节点到所有点的需要改变的边的条数。(自上向下) 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 const int N=200020; 8 struct Point 9 { 10 int v,w; 1... 阅读全文
posted @ 2013-07-10 09:02 自力创辉煌 阅读(211) 评论(0) 推荐(0)
摘要: 题意: 求每个点的最远距离。树形dp,做了两天,感觉就是从子节点得到父节点。此题要用到两次dfs, 第一次dfs1用来求所有节点在他子树范围内到叶子节点的最长距离和次长距离。dp1,和dp2第二次dfs2 ,求f【】,如果dp1[s]==dp1[x]+len (s为父节点,x为子节点),则 x 在最长树的分支上,f[x]=max(f[s]+len,dp2[s]+len);所以f【x】就等于f父节点加上到子节点的距离和父节点的次长加上到x节点的距离的两者的最大值。如果 不相等,则代表x节点不在父节点最长的分支上。则f【x】就等于f父节点到x节点的距离和父节点的最长距离加上到子节点距离 两者的最. 阅读全文
posted @ 2013-07-09 08:28 自力创辉煌 阅读(141) 评论(0) 推荐(0)
摘要: 题意就是设置最少的哨兵,能够看到所有的路。二分图也能解决,即二分图最小点覆盖 用vector超内存了, 1 #include 2 #include 3 #include 4 using namespace std; 5 #define MAXN 1600 6 #define MAXE 300000 7 struct Edge 8 { 9 int v; // 10 int next;11 }edge[MAXE];12 int head[MAXN]; // 每个点临接的边13 int cnt ; // 边的条数14 int n ; // 点的个数15 int path[MAXN];... 阅读全文
posted @ 2013-07-08 10:07 自力创辉煌 阅读(104) 评论(0) 推荐(0)
摘要: 上午看了想了好长时间,下午用了一个多小时才写出来,主要对回溯没怎么写过。第一题 树形dp。题意就是有关系的两个人不能同时出现。dp1【s】 表示 s点去。dp2【s】 表示s点不去。dp1【s】+=dp2【x】。 //s点去,ze x点不去 (s为父节点)。dp2【s】+=max(dp1【x】,dp2【x】);// s点不去,则x去或不去的最大的一个 1 #include 2 #include 3 #include 4 #include 5 using namespace std; 6 vectorV[6006]; 7 int vis[6006]; 8 int dp1[6006];//去 9. 阅读全文
posted @ 2013-07-07 16:31 自力创辉煌 阅读(202) 评论(0) 推荐(0)
摘要: http://poj.org/problem?id=3264#include #include #include #include using namespace std; #define L(x) (x >1; build(L(t),l,mid); build(R(t),mid,r); node[t].mmax=max(node[L(t)].mmax,node[R(t)].mmax); node[t].mmin=min(node[L(t)].mmin,node[R(t)].mmin); } void get(int t,int l,int r) { ... 阅读全文
posted @ 2012-10-27 02:34 自力创辉煌 阅读(202) 评论(0) 推荐(0)
摘要: 更新线段,并查询线段。http://poj.org/problem?id=3468#include #include #include using namespace std; #define maxn 1000020 __int64 sum[4*maxn]; __int64 col[4*maxn]; void Pushup(int rt) { sum[rt]=sum[rt>1)); sum[rt>1); col[rt]=0; } } void Update(int L,int R,int c,int l,int r,int rt) { ... 阅读全文
posted @ 2012-10-26 01:34 自力创辉煌 阅读(104) 评论(0) 推荐(0)
摘要: 线段树就是许多线段组成的,并对每条线段进行操作,线段树的节点满足二叉树,所以某个节点的左右儿子是 2*rt,和2*rt+1;举例说明:已知线段[2,5] [4,6] [0,7];求点2,4,7分别出现了多少次在[0,7]区间上建立一棵满二叉树:(为了和已知线段区别,用【】表示线段树中的线段) 【0,7】 / \ 【0,3】 【4,7】 / \ / \ 【0,1】 【2,3】 【4,5】 【6,7】 / \ / \ / \ / \【0,0】 【1,1】 【2,2】 【3,3】 【4,4】 【5,5】 【6,6】 【7,7】三条已知线段插入过程:[2,5]-... 阅读全文
posted @ 2012-10-22 21:19 自力创辉煌 阅读(116) 评论(0) 推荐(0)
摘要: 题目中说c #include #define maxn 100002 int vis[maxn]; int sum[maxn]; int arr[maxn]; int main() { int n,i,m; while(1) { scanf("%d%d",&m,&n); if(m==0&&n==0) break; arr[0]=0; memset(sum,0,sizeof(sum)); for(i=1;i<=n;i++) { scanf("%d",&a... 阅读全文
posted @ 2012-10-20 18:59 自力创辉煌 阅读(155) 评论(0) 推荐(0)