NOIP模拟赛10
T1 [HAOI2010]软件安装
https://daniu.luogu.org/problem/show?pid=2515
树上背包,如果有i必须有j,j作为i的父节点
O(nm²)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 101
#define M 501
using namespace std;
int y[N],h[N],x[N];
int dfn[N],low[N],st[N],top,tot;
bool vis[N];
int cnt,ny[N],nh[N],col[N];
int dp[N][M],m;
int to[M],nxt[M],front[N];
int to2[M],nxt2[M],front2[M];
void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
}
void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
}
void add2(int u,int v)
{
to2[++tot]=v; nxt2[tot]=front2[u]; front2[u]=tot;
}
void tarjan(int u)
{
dfn[u]=low[u]=++tot;
vis[u]=true;
st[++top]=u;
if(x[u])
{
if(!dfn[x[u]]) tarjan(x[u]),low[u]=min(low[u],low[x[u]]);
else if(vis[x[u]]) low[u]=min(low[u],dfn[x[u]]);
}
if(dfn[u]==low[u])
{
cnt++;
while(st[top]!=u)
{
ny[cnt]+=y[st[top]];
nh[cnt]+=h[st[top]];
vis[st[top]]=false;
col[st[top]]=cnt;
top--;
}
ny[cnt]+=y[u];
nh[cnt]+=h[u];
vis[u]=false;
col[u]=cnt;
top--;
}
}
void dfs(int now)
{
for(int i=ny[now];i<=m;i++) dp[now][i]=nh[now];
for(int i=front2[now];i;i=nxt2[i])
{
dfs(to2[i]);
for(int j=m;j>=ny[now];j--)
for(int k=;k<=j-ny[now];k++)
dp[now][j]=max(dp[now][j],dp[now][j-k]+dp[to2[i]][k]);
}
}
int main()
{
int n;
read(n); read(m);
for(int i=;i<=n;i++) read(y[i]);
for(int i=;i<=n;i++) read(h[i]);
for(int i=;i<=n;i++)
{
read(x[i]);
add(x[i],i);
}
tot=;
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
memset(vis,false,sizeof(vis));
tot=;
for(int i=;i<=n;i++)
if(col[i]!=col[x[i]])
add2(col[x[i]],col[i]),vis[col[i]]=true;
for(int i=;i<=cnt;i++)
if(!vis[i]) add2(,i);
dfs();
printf("%d",dp[][m]);
}
可以优化值O(nm),即每次都将要处理的子树和根节点看做一个整体
在dfs子树前,将根节点的值赋值给子节点
具体参考XCH的《浅谈几类背包问题》
https://wenku.baidu.com/view/d59b42fe04a1b0717fd5dd72.html
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=,maxm=;
struct edge
{
int u,v;
};
struct edge Edge[maxn];
int bel[maxn],n,m,col,hi[maxn],yi[maxn],head[maxn],tag,dp[maxn][maxm];
int E[maxn<<],V[maxn<<],cnt,ci[maxn],vi[maxn],dfn[maxn],low[maxn];
int sta[maxn],top,num;
bool vis[maxn];
inline void in(int &now)
{
char Cget;now=;while((Cget=getchar())>''||Cget<'');
while(Cget>=''&&Cget<='')now=now*+Cget-'',Cget=getchar();
}
void tarjan(int now)
{
dfn[now]=low[now]=++tag,sta[++top]=now;
for(int i=head[now];i;i=E[i])
if(!bel[V[i]])
if(dfn[V[i]]) low[now]=min(low[now],dfn[V[i]]);
else tarjan(V[i]),low[now]=min(low[now],low[V[i]]);
if(low[now]==dfn[now])
{
col++;
while(sta[top]!=now)
{
bel[sta[top]]=col;
vi[col]+=yi[sta[top]];
ci[col]+=hi[sta[top]];
top--;
}
bel[now]=col,vi[col]+=yi[now],ci[col]+=hi[now],top--;
}
}
void dfs(int now,int lit)
{
if(lit<=) return;
int v;
for(int i=head[now];i;i=E[i])
if(lit>=vi[V[i]])
{
v=V[i];
for(int e=;e<=lit;e++)
dp[v][e]=dp[now][e];
dfs(v,lit-vi[v]);
for(int e=lit;e>=vi[v];e--)
dp[now][e]=max(dp[now][e],dp[v][e-vi[v]]+ci[v]);
}
}
int main()
{
in(n),in(m);
for(int i=;i<=n;i++) in(yi[i]);
for(int i=;i<=n;i++) in(hi[i]);
int u,v;
for(int i=;i<=n;i++)
{
in(u),v=i;
if(u!=)
{
E[++cnt]=head[u],V[cnt]=v,head[u]=cnt;
}
Edge[i].u=u,Edge[i].v=v;
}
for(int i=;i<=n;i++)
if(!dfn[i])
tarjan(i);
num=n,cnt=;
memset(head,,sizeof(head));
for(int i=;i<=num;i++)
if(bel[Edge[i].u]!=bel[Edge[i].v])
{
if(Edge[i].u!=)
{
E[++cnt]=head[bel[Edge[i].u]];
V[cnt]=bel[Edge[i].v];
head[bel[Edge[i].u]]=cnt;
vis[bel[Edge[i].v]]=true;
}
else
{
E[++cnt]=head[n+];
V[cnt]=bel[Edge[i].v];
vis[bel[Edge[i].v]]=true;
head[n+]=cnt;
}
}
for(int i=;i<=col;i++)
if(!vis[i])
{
E[++cnt]=head[n+];
V[cnt]=i;
head[n+]=cnt;
}
dfs(n+,m);
cout<<dp[n+][m];
fclose(stdin),fclose(stdout);
return ;
}
T2 codevs 3305 水果姐逛水果街Ⅱ
http://codevs.cn/problem/3305/
树链剖分维护前面减后面的最大值,后面减前面的最大值
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define lson k<<1
#define rson k<<1|1
using namespace std;
const int N=;
int front[N],to[N<<],nxt[N<<],tot,dfn[N],id[N],a[N];
int ls[N<<],rs[N<<],mi[N<<],mx[N<<];
int n,siz[N],dep[N],bl[N],fa[N];
struct node
{
int x,y,z;
};
inline void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-'' ; c=getchar(); }
}
void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
}
void dfs1(int x,int f)
{
siz[x]=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=f)
{
dep[to[i]]=dep[x]+;
fa[to[i]]=x;
dfs1(to[i],x);
siz[x]+=siz[to[i]];
}
}
void dfs2(int x,int top)
{
bl[x]=top;
dfn[x]=++tot;
id[tot]=x;
int y=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x] && siz[to[i]]>siz[y]) y=to[i];
if(!y) return;
dfs2(y,top);
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x] && to[i]!=y) dfs2(to[i],to[i]);
}
inline void up(int k)
{
mi[k]=min(mi[lson],mi[rson]);
mx[k]=max(mx[lson],mx[rson]);
ls[k]=max(mx[rson]-mi[lson],max(ls[lson],ls[rson]));
rs[k]=max(mx[lson]-mi[rson],max(rs[lson],rs[rson]));
}
void build(int k,int l,int r)
{
if(l==r)
{
mi[k]=mx[k]=a[id[l]];
return;
}
int mid=l+r>>;
build(lson,l,mid);
build(rson,mid+,r);
up(k);
}
int getlca(int u,int v)
{
while(bl[u]!=bl[v])
{
if(dep[bl[u]]<dep[bl[v]]) swap(u,v);
u=fa[bl[u]];
}
return dep[u]>dep[v] ? v : u;
}
node qleft(int k,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr) return (node){mi[k],mx[k],ls[k]};
int mid=l+r>>;
if(opr<=mid) return qleft(lson,l,mid,opl,opr);
if(opl>mid) return qleft(rson,mid+,r,opl,opr);
node lch=qleft(lson,l,mid,opl,opr),rch=qleft(rson,mid+,r,opl,opr);
return (node){min(lch.x,rch.x),max(lch.y,rch.y),max(rch.y-lch.x,max(lch.z,rch.z))};
}
node fleft(int x,int y)
{
if(bl[x]==bl[y]) return qleft(,,n,dfn[y],dfn[x]);
node lch,rch=qleft(,,n,dfn[bl[x]],dfn[x]);
x=fa[bl[x]];
//if(id[bl[x]]<id[bl[y]]) swap(x,y);
while(bl[x]!=bl[y])
{
lch=qleft(,,n,dfn[bl[x]],dfn[x]);
rch.z=max(rch.y-lch.x,max(lch.z,rch.z));
rch.x=min(lch.x,rch.x),rch.y=max(lch.y,rch.y);
x=fa[bl[x]];
}
lch=qleft(,,n,dfn[y],dfn[x]);
rch.z=max(rch.y-lch.x,max(lch.z,rch.z));
rch.x=min(lch.x,rch.x),rch.y=max(lch.y,rch.y);
return rch;
}
node qright(int k,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr) return (node){mi[k],mx[k],rs[k]};
int mid=l+r>>;
if(opr<=mid) return qright(lson,l,mid,opl,opr);
if(opl>mid) return qright(rson,mid+,r,opl,opr);
node lch=qright(lson,l,mid,opl,opr),rch=qright(rson,mid+,r,opl,opr);
return (node){ min(lch.x,rch.x),max(lch.y,rch.y),max(lch.y-rch.x,max(lch.z,rch.z))};
}
node fright(int x,int y)
{
if(bl[x]==bl[y]) return qright(,,n,dfn[y],dfn[x]);
node rch=qright(,,n,dfn[bl[x]],dfn[x]),lch;
x=fa[bl[x]];
// if(id[bl[x]]<id[bl[y]]) swap(x,y);
while(bl[x]!=bl[y])
{
lch=qright(,,n,dfn[bl[x]],dfn[x]);
rch.z=max(lch.y-rch.x,max(lch.z,rch.z));
rch.x=min(lch.x,rch.x),rch.y=max(lch.y,rch.y);
x=fa[bl[x]];
}
lch=qright(,,n,dfn[y],dfn[x]);
rch.z=max(lch.y-rch.x,max(lch.z,rch.z));
rch.x=min(lch.x,rch.x),rch.y=max(lch.y,rch.y);
return rch;
}
int main()
{
memset(mi,/,sizeof(mi));
int m,u,v,lca;
read(n);
for(int i=;i<=n;i++) read(a[i]);
for(int i=;i<n;i++) read(u),read(v),add(u,v);
dfs1(,);
tot=;
dfs2(,);
build(,,n);
read(m);
while(m--)
{
read(u),read(v);
lca=getlca(u,v);
if(u==lca) printf("%d\n",fleft(v,lca).z);
else if(v==lca) printf("%d\n",fright(u,lca).z);
else
{
node lch=fleft(v,lca),rch=fright(u,lca);
printf("%d\n",max(lch.y-rch.x,max(lch.z,rch.z)));
}
}
return ;
}
T3 hdu 1798 50 years, 50 colors
http://acm.hdu.edu.cn/showproblem.php?pid=1498
枚举颜色
如果(x,y)有气球,则由x向y连边
然后二分图最小点覆盖=最大匹配数
#include<cstdio>
#include<cstring>
using namespace std;
int a[][];
bool v[],vv[];
int match[];
int tot,front[],to[],nxt[];
int ans[];
void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
}
bool dfs(int u)
{
for(int i=front[u];i;i=nxt[i])
if(!v[to[i]])
{
v[to[i]]=true;
if(!match[to[i]] || dfs(match[to[i]]))
{
match[to[i]]=u;
return true;
}
}
return false;
}
int main()
{
//freopen("T3.in","r",stdin);
//freopen("T3.out","w",stdout);
int n,k,res;
bool ok;
while(scanf("%d%d",&n,&k))
{
if(!n) return ;
memset(vv,false,sizeof(vv));
ok=false;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
scanf("%d",&a[i][j]),vv[a[i][j]]=true;
ans[]=;
for(int i=;i<=;i++)
if(vv[i])
{
tot=;
memset(front,,sizeof(*front)*(n+));
res=;
for(int j=;j<=n;j++)
for(int k=;k<=n;k++)
if(a[j][k]==i) add(j,k);
memset(match,,sizeof(*match)*(n+));
for(int j=;j<=n;j++)
{
memset(v,false,sizeof(*v)*(n+));
if(dfs(j)) res++;
}
if(res>k) ans[++ans[]]=i;
}
if(!ans[]) printf("-1");
else
{
for(int i=;i<ans[];i++) printf("%d ",ans[i]);
printf("%d",ans[ans[]]);
}
printf("\n");
}
}
NOIP模拟赛10的更多相关文章
- 【noip模拟赛10】奇怪的贸易 高精度
描述 刚结束了CS战斗的小D又进入了EVE的游戏世界,在游戏中小D是一名商人,每天要做的事情就是在这里买东西,再运到那里去卖.这次小D来到了陌生的X星,X星上有n种货物,小D决定每种都买走一些,他用a ...
- NOIP模拟赛10 题解
t3: 题意 给你一棵树,然后每次两种操作:1.给一个节点染色 : 2. 查询一个节点与任意已染色节点 lca 的权值的最大值 分析 考虑一个节点被染色后的影响:令它的所有祖先节点(包括自身)的所有除 ...
- 10.17 NOIP模拟赛
目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...
- 10.16 NOIP模拟赛
目录 2018.10.16 NOIP模拟赛 A 购物shop B 期望exp(DP 期望 按位计算) C 魔法迷宫maze(状压 暴力) 考试代码 C 2018.10.16 NOIP模拟赛 时间:2h ...
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
随机推荐
- Python:模块学习——os模块
os模块提供了多个访问操作系统服务的功能 os模块中一些重要的函数和变量 os.name 显示当前使用平台 os.getcwd() 显示当前Python脚本工作路径 os.listdir('dirna ...
- 网站UI分析
本次网站UI分析我选择的是我们石家庄铁道大学的网站,首先对于网站的分析建立在我经常使用鼠须的基础上,我可以很好的站在用户的角度来进行分析,否则对于你不熟悉的网站你可能是不能很好地体验到他的 结构. U ...
- sql数据库表容量
标题:SQL Server 的最大容量规范 数据库的文件大小,文件数量都有限制. 表的大小也有限制,如果表过大,查询效率就会下降,考虑对数据进行分割,对历史数据进行独立存储.
- psp 第二周
11号 12号 类别c 内容c 开始时间s 结 ...
- 实现全站 HTTPS ,为什么国内网站总是那么slow&&low呀!
1 https://konklone.com/post/switch-to-https-now-for-free# https://theintercept.com/2014/11/20/non-pr ...
- 第100天:CSS3中animation动画详解
CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation: 一.Animation定义动画 CSS3的Animation是由“keyframes”这个属性来 ...
- stm32f4xx系统总线架构
最近有人在STMCU社区网站咨询如下问题: 由于实验需要,要用到STM32F407的两个DMA并用定时器触发,在使用过程中发现DMA1无法把GPIO的IDR上的数据传输到内存,调试过程中出现DMA1的 ...
- bzoj1318[spoj 744] Longest Permutation
题意 给出一个长度为n的,所有元素大小在[1,n]的整数数列,要求选出一个尽量长的区间使得区间内所有元素组成一个1到区间长度k的排列,输出k的最大值 n<=1e5 分析 不会做,好菜啊.jpg ...
- 【bzoj5206】[Jsoi2017]原力 根号分治+STL-map
题目描述 一个原力网络可以看成是一个可能存在重边但没有自环的无向图.每条边有一种属性和一个权值.属性可能是R.G.B三种当中的一种,代表这条边上原力的类型.权值是一个正整数,代表这条边上的原力强度.原 ...
- Collection接口框架
1. Collection接口 其主要的UML类图: Collection接口继承自Iterable接口.Iterable接口中定义了Iterable方法,该方法会返回一个迭代器,用于遍历合集中的元素 ...