BZOJ NOI十连测 第一测 T2



思路:看到这题,就感觉是一道很熟悉的题目:
http://www.cnblogs.com/qzqzgfy/p/5535821.html
只不过这题的K最多可以到N,而且边权不再只是1,考试的时候yy了一下做法:
找k次直径,第一次把边取反,要是第二次再取到同样的边,那就把它变成0,毕竟每条边只经过2次嘛,YY的很好,实际上,交上去,5分TAT
后来听以为神犇说不是取0,而是继续取反,每条边取一次就取反一次,woc..
PS还有一点:一开始我是准备找出里面一点,然后bfs找最远和次远的点,然后把路径取反的,后面想想太SB了,毕竟这两个点是有可能有相交路径的。。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
int dis[],val[],mxdis,d[],p;
int tot,go[],next[],first[],n,k,C,cnt=,ans1,ans2,id[];
int pre[],edge[],op[],S,T,vis[],c[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void insert(int x,int y,int z){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
val[tot]=z;
}
void add(int x,int y,int z){
insert(x,y,z);op[tot]=tot+;insert(y,x,z);op[tot]=tot-;
}
void dfs1(int x,int fa){
d[x]=;ll mx1=,mx2=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==fa) continue;
dfs1(pur,x);
if (d[pur]+val[i]>mx1) mx2=mx1,mx1=d[pur]+val[i];
else if (d[pur]+val[i]>mx2) mx2=d[pur]+val[i];
}
if (mxdis<mx1+mx2) mxdis=mx1+mx2,S=x;
}
void clear(int x){
for (int i=x;i!=S;i=pre[i]){
val[edge[i]]=-val[edge[i]];val[op[edge[i]]]=-val[op[edge[i]]];
}
}
int bfs(int x){
int h=,t=;
ll mx=;int Id=x;
for (int i=;i<=n;i++) dis[i]=vis[i]=pre[i]=edge[i]=c[i]=;
c[]=x;
vis[x]=;
while (h<=t){
int now=c[h++];
for (int i=first[now];i;i=next[i]){
int pur=go[i];
if (vis[pur]) continue;
dis[pur]=dis[now]+val[i];
pre[pur]=now;
edge[pur]=i;
vis[pur]=;
c[++t]=pur;
}
}
for (int i=;i<=n;i++)
if (mx<dis[i]) mx=dis[i],Id=i;
return Id;
}
void clear(){
T=bfs(S);
ll sx=;int Id=S;
for (int i=;i<=n;i++)
if (i!=S&&i!=T&&sx<dis[i]) sx=dis[i],Id=i;
clear(Id);clear(T);
}
void Find_longest(){
mxdis=-0x7fffffff;
dfs1(,);
clear();
}
void dfs(int x,int fa){
int mx1=,mx2=;d[x]=;int id1=x,id2=x;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==fa) continue;
dfs(pur,x);
if (d[pur]+val[i]>mx1) mx2=mx1,mx1=d[pur]+val[i],id2=id1,id1=id[pur];
else if (d[pur]+val[i]>mx2) mx2=d[pur]+val[i],id2=id[pur];
}
id[x]=id1;
d[x]=mx1;
if (mxdis<mx1+mx2) mxdis=mx1+mx2,ans1=id1,ans2=id2;
}
void dfss(int x,int y,int fa){
if (!x||!y) return;
if (x==y) {p=;return;}
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==fa) continue;
dfss(pur,y,x);
if (p) {val[i]=-val[i],val[op[i]]=-val[op[i]];return;}
}
}
int main(){
while (scanf("%d",&n)!=EOF){
k=read();C=read();
tot=;
int sum=;
for (int i=;i<=n;i++) first[i]=;
for (int i=;i<n;i++){
int x=read(),y=read(),z=read();
x++;y++;
add(x,y,z);
sum+=z;
}
sum*=;
for (int i=;i<=k;i++){
mxdis=;
dfs(,);
if (mxdis<C) break;
sum=sum-mxdis+C;
p=;
dfss(ans1,ans2,);
}
printf("%d\n",sum);
}
}
然后听说有树形dp做法,由于每条边至多经过2次。假如每次穿越都新加了一条"穿越边",每次穿越都新加了2个"新点",假如子树x内有k个新点,那么(fa[x],x)这条边经过的边奇偶性和k个奇偶性相同,因为要从0出发,再回到0,这是个欧拉回路,因此进入子树p有x条边的话,离开子树p也必须是x条边,因此,奇偶性相同就得证了,由此我们设dp方程
f[x][p]代表x的子树,有p个新节点的最小代价,然后用树上背包做就好了,(虽然这看起来像n^3,但是是n^2.....)
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x3f3f3f3f
int tot,go[],first[],next[],val[];
int son[],f[][],g[],n,K,C;
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void insert(int x,int y,int z){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
val[tot]=z;
}
void add(int x,int y,int z){
insert(x,y,z);insert(y,x,z);
}
void dfs(int x,int fa,int y){
son[x]=;
for (int i=;i<=n;i++) f[x][i]=inf;
f[x][]=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==fa) continue;
dfs(pur,x,val[i]);
for (int j=;j<=son[x];j++) g[j]=f[x][j],f[x][j]=inf;
for (int j=;j<son[x];j++)
for (int k=;k<=son[pur];k++)
f[x][j+k]=std::min(f[x][j+k],g[j]+f[pur][k]);
son[x]+=son[pur];
}
for (int i=son[x];i>=;i--)
f[x][i]=std::min(f[x][i],f[x][i-]);
for (int i=;i<=son[x];i++) f[x][i]+=((i%==)+)*y;
}
int main(){
while (scanf("%d",&n)!=EOF){
K=read();C=read();
tot=;
for (int i=;i<=n;i++)
first[i]=;
for (int i=;i<n;i++){
int x=read(),y=read(),z=read();
x++;y++;
add(x,y,z);
}
dfs(,,);
int ans=inf;
for (int i=;i<=K&&i*<=n;i++)
ans=std::min(ans,f[][i*]+C*i);
printf("%d\n",ans);
}
}
BZOJ NOI十连测 第一测 T2的更多相关文章
- BZOJ NOI十连测 第二测 T2
思路:20%可以搜索.. #include<algorithm> #include<cstdio> #include<cmath> #include<cstr ...
- BZOJ NOI十连测 第一测 T1
思路:首先考虑t=1的情况,t等于1,那么所有位置的颜色相同,我们不用考虑概率的问题,那么,k+d*x在模d下都相等,我们考虑预处理一个数组s[i][j],代表d为i,起始位置为j的等差数列的和,这个 ...
- BZOJ NOI十连测 第二测 T1
出题人居然是个哲学家.. 26%的程序,太SB了...本来我的想法也是二分+贪心,但是贪心是个怪怪的SX贪心.. #include<algorithm> #include<cstdi ...
- 痞子衡嵌入式:测一测i.MXRT1170 Raw NAND启动时间(从POR到进App的Reset_Handler)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1170 Raw NAND启动时间. 关于i.MXRT1170这颗划时代的MCU,痞子衡去年10月在其刚发布的时候, ...
- 「NOI十联测」深邃
「NOI十联测」深邃 要使得最大的连通块最小,显然先二分答案. 先固定1结点为根. 对于一个果实,显然是先处理子树中未分配的点,再向外延伸. 每个结点记录一个\(si[]\),表示子树中未分配的点数, ...
- 「NOI十联测」奥义商店
「NOI十联测」奥义商店 若lzz想花费最少的钱,那么显然要选择数目较少的颜色. 先考虑暴力的写法. 每次向两边统计,每个物品要求被买的概率可以由上一个物品推出. now=1;//now 被买概率 M ...
- 「NOI十联测」黑暗
「NOI十联测」黑暗 \(n\) 个点的无向图,每条边都可能存在,一个图的权值是连通块个数的 \(m\) 次方,求所有可能的图的权值和.(n≤30000,m≤15) 令\(ans[n][m]\)为n个 ...
- NOI十连测 第五测 T2
思路:考虑建立可持久化线段树,第一层维护的是i这个位置的next位置,第二层,维护的是接下来走这个字符会到哪个节点. 感觉很巧妙啊,不愧是Claris #include<algorithm> ...
- NOI十连测 第四测 T2
思路:线段树套可持久化treap,可持久化treap我还是第一次听说.. 改题的时候没看数据范围..乱开数组T_T #include<algorithm> #include<cstd ...
随机推荐
- 蓝牙芯片NRF51822入门学习1:时间管理
前言 之前辞职找工作的时候发现,很多公司希望招聘蓝牙技术方面的人才,所以干脆丢开LWIP静下心来学习蓝牙技术.原本以为一两星期能基本学会的,谁知道所选的蓝牙芯片nrf51822是个坑货,坑了我一个月. ...
- .NET自动字符编码识别程序库 NChardet
什么是NChardet NChardet是mozilla自动字符编码识别程序库chardet的.NET实现,它移植自jchardet,chardet的java版实现,可实现对给定字符流的编码探测. N ...
- Linux下编译第三方库的问题
因为各个Linux发行版之间的差异还是挺大的,有一些预安装在系统上的基本库是不一样的(不仅仅是版本,有一些是有和无的区别). 那么问题来了: 编译第三方库./configure的时候一般我们不会定制那 ...
- [置顶] Android EditText/TextView使用SpannableString显示复合文本
在Android中EditText用于编辑文本,TextView用于显示文本,但是有时候我们需要对其中的文本进行样式等方面的设置.Android为我们提供了SpannableString类来对指定文本 ...
- android的原理--为什么我们不需要手动关闭程序
内容搜集自网络,有所删改 不用在意剩余内存的大小,其实很多人都是把使用其他系统的习惯带过来来了.android大多应用没有退出的设计其实是有道理的,这和系统对进程的调度机制有关系.如果你知 ...
- Red Hat Enterprise Linux 7的新功能
简介红帽最新版本的旗舰平台交付显著增强的可用性. 性能和可靠性. 丰富的新功能为架构. 系统管理员和开发人员提供所需的资源以更高效地进行创新和管理.架构师: 红帽® 企业 Linux® 7 适合 ...
- ECharts API
From:http://echarts.baidu.com/echarts2/doc/doc.html 简介 名词解析 图表类型 line bar scatter k pie radar chord ...
- OS error set
Failed to resolve/decode supposed IPv4 source addres Failed to resolve/decode supposed IPv4 source a ...
- C++空类中的默认函数
定义一个空的C++类,例如 class Empty { } 一个空的class在C++编译器处理过后就不再为空,编译器会自动地为我们声明一些member function,一般编译过去就相当于 cla ...
- iOS8 Core Image In Swift:人脸检测以及马赛克
iOS8 Core Image In Swift:自动改善图像以及内置滤镜的使用 iOS8 Core Image In Swift:更复杂的滤镜 iOS8 Core Image In Swift:人脸 ...