思路:看到这题,就感觉是一道很熟悉的题目:

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的更多相关文章

  1. BZOJ NOI十连测 第二测 T2

    思路:20%可以搜索.. #include<algorithm> #include<cstdio> #include<cmath> #include<cstr ...

  2. BZOJ NOI十连测 第一测 T1

    思路:首先考虑t=1的情况,t等于1,那么所有位置的颜色相同,我们不用考虑概率的问题,那么,k+d*x在模d下都相等,我们考虑预处理一个数组s[i][j],代表d为i,起始位置为j的等差数列的和,这个 ...

  3. BZOJ NOI十连测 第二测 T1

    出题人居然是个哲学家.. 26%的程序,太SB了...本来我的想法也是二分+贪心,但是贪心是个怪怪的SX贪心.. #include<algorithm> #include<cstdi ...

  4. 痞子衡嵌入式:测一测i.MXRT1170 Raw NAND启动时间(从POR到进App的Reset_Handler)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1170 Raw NAND启动时间. 关于i.MXRT1170这颗划时代的MCU,痞子衡去年10月在其刚发布的时候, ...

  5. 「NOI十联测」深邃

    「NOI十联测」深邃 要使得最大的连通块最小,显然先二分答案. 先固定1结点为根. 对于一个果实,显然是先处理子树中未分配的点,再向外延伸. 每个结点记录一个\(si[]\),表示子树中未分配的点数, ...

  6. 「NOI十联测」奥义商店

    「NOI十联测」奥义商店 若lzz想花费最少的钱,那么显然要选择数目较少的颜色. 先考虑暴力的写法. 每次向两边统计,每个物品要求被买的概率可以由上一个物品推出. now=1;//now 被买概率 M ...

  7. 「NOI十联测」黑暗

    「NOI十联测」黑暗 \(n\) 个点的无向图,每条边都可能存在,一个图的权值是连通块个数的 \(m\) 次方,求所有可能的图的权值和.(n≤30000,m≤15) 令\(ans[n][m]\)为n个 ...

  8. NOI十连测 第五测 T2

    思路:考虑建立可持久化线段树,第一层维护的是i这个位置的next位置,第二层,维护的是接下来走这个字符会到哪个节点. 感觉很巧妙啊,不愧是Claris #include<algorithm> ...

  9. NOI十连测 第四测 T2

    思路:线段树套可持久化treap,可持久化treap我还是第一次听说.. 改题的时候没看数据范围..乱开数组T_T #include<algorithm> #include<cstd ...

随机推荐

  1. XML基础<第一篇>

    一.XML简介 XML是一种标记语言,用于描述数据,它提供一种标准化的方式来来表示文本数据.XML文档以.xml为后缀.需要彻底注意的是XML是区分大小写的. 先从一个简单的XML例子来了解下xml基 ...

  2. Resharper上手指南

    原文http://www.cnblogs.com/renji/archive/2007/12/11/resharper.html Resharper上手指南 我是visual studio的忠实用户, ...

  3. linux下通过yum安装svn及配置

    1.环境centos6.4 2.安装svnyum -y install subversion 3.配置 建立版本库目录mkdir /www/svndata svnserve -d -r /www/sv ...

  4. VC++ 2013 开发windows窗体程序

    开发工具版本:Visual Studio Express 2013 for Windows Desktop 1. 新建Visual C++下面的"Win32 Project" 2. ...

  5. bzoj1379 [Baltic2001]Postman

    Description 邮递员每天给N个村子的人送信,每个村子可能在某个十字路口上,或一条路的中央. 村子里的人都希望早点收到信,因此与邮递员达成一个协议:每个村子都有一个期望值Wi,如果这个村子是邮 ...

  6. POJ1664(简单动态规划)

    #include<iostream> #include<string> #include<cstring> using namespace std; ][]; vo ...

  7. Hdu2425-Hiking Trip(优先队列搜索)

    Hiking in the mountains is seldom an easy task for most people, as it is extremely easy to get lost ...

  8. 【HDU1198】Farm Irrigation(回溯+记忆化搜索)

    数据流小,深搜即可.有些暴力.看其他人的题解用二维转换成一维做的并查集很巧妙,马上去研究一下!! #include <iostream> #include <cstring> ...

  9. JS~Boxy和JS模版实现一个标准的消息提示框

    面向对象的封装 面向对象一个入最重要的特性就是“封装”,将一些没有必要公开的方法和属性以特定的方式进行组装,使它对外只公开一个接口,外界在调用它时,不需要关注它实现的细节,而只要关注它的方法签名即可, ...

  10. .NET 中使用 HttpWebResponse 时 Cookie 的读取

    今天把一个网站登录配置到以前写的蜘蛛程序中,发现不能成功登录.检查后才发现,那个网站在登录成功后,输出了一个特殊路径的 Cookie,由于是使用 HttpWebRequest.Cookies 来获取的 ...