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 ...
随机推荐
- 去掉java反编译(JD-GUI)生成的源文件中注释
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...
- Java Fuck Bignumber
为了熟悉java , 开一套poj大数处理的题来写. ------------------------------------------------------------------- A: (1 ...
- javascrpit开发连连看记录-小游戏
工作之余,总想做点什么有意思的东西.但是苦于不知道做什么,也就一直没有什么动作.在一个午饭后,跟@jedmeng和@墨尘聊天过程中,发现可以写一些小东西来练练手,有以下几点好处: 1. ...
- LinQ to SQL 查询
LINQ to SQL 是将对象关系映射到.NET框架中的一种实现.它可以将关系数据库映射为.NET Framework中的一些类. 然后,开发人员就可以通过使用 LINQ to SQL对数据库中的数 ...
- 检测iOS系统的定位服务
[CLLocationManager locationServicesEnabled]检测的是整个iOS系统的位置服务开关
- 机房收费系统合作版(三)——UI思索
案件追踪系统1.0暂告一段落.验收过程中.MR MI针对UI界面提出了很多自己的想法. 针对TGB项目的UI设计我也有我的感受: 1.不论大小项目.仅仅要一看界面准有70%到80%熟悉度. 2.一看这 ...
- hdu 5071 Chat(模拟|Splay)
Chat Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total Sub ...
- android——屏幕适配大全(转载)
http://my.oschina.net/u/2008084/blog/496161 一.适配可行性 早在Android设计之初就考虑到了这一点,为了让app适应标准or山寨屏幕,google已经有 ...
- vue中关于computed的一点理解
computed相当于属性的一个实时计算,如果实时计算里关联了对象,那么当对象的某个值改变的时候,同事会出发实时计算. 例子: <body id="content"> ...
- 【js】判断设备类型,访问相应的网站
引入 function uaredirect(f) { try { if (document.getElementById("bdmark") != null) { return ...