Description

马克(Mirko)和斯拉夫克(Slavko)正在为克罗地亚举办的每年一次的双人骑车马拉松赛而紧张训练。他们需要选择一条训练路径。 他们国家有N个城市和M条道路。每条道路连接两个城市。这些道路中恰好有N-1条是铺设好的道路,其余道路是未经铺设的土路。幸运的是,每两个城市之间都存在一条由铺设好的道路组成的通路。换句话说,这N个城市和N-1条铺设好的道路构成一个树状结构。 此外,每个城市最多是10条道路的端点。 一条训练路径由某个城市开始,途经一些道路后在原来起始的城市结束。因为马克和斯拉夫克喜欢去看新城市,所以他们制定了一条规则:绝不中途穿越已经去过的城市,并且绝不在相同的道路上骑行两次(不管方向是否相同)。训练路径可以从任何一个城市开始,并且不需要访问所有城市。 显然,坐在后座的骑行者更为轻松,因为坐在前面的可以为他挡风。为此,马克和斯拉夫克在每个城市都要调换位置。为了保证他们的训练强度相同,他们要选择一条具有偶数条道路的路径。 马克和斯拉夫克的竞争者决定在某些未经铺设的土路上设置路障,使得他们两人不可能找到满足上述要求的训练路径。已知在每条土路上设置路障都有一个费用值(一个正整数),并且竞争者不能在铺设好的道路上设置路障。 任务 给定城市和道路网的描述,写一个程序计算出为了使得满足上述要求的训练路径不存在,而需要的设置路障的最小总费用。

Input

输入的第一行包含两个整数N和M,(2≤N≤1000,N-1≤M≤5000),分别表示城市和道路的个数。 接下来的M行每行包含3个整数A, B和C(1≤A≤N, 1≤B≤N, 0≤C≤10 000), 用来描述一条道路。A和B是不同的整数,表示由这条道路直接相连的两个城市。对于铺设好的道路C是0;对于土路,c是在该条路上设置路障所需的费用值。 每个城市最多是10条道路的端点。任意两个城市都不会有多于一条直接相连的道路。

Output

输出包含一个整数,表示求出的最小总费用。

Sample Input

5 8
2 1 0
3 2 0
4 3 0
5 4 0
1 3 2
3 5 2
2 4 5
2 5 1

Sample Output

5

HINT

正解:状压$dp$。

这道题应该是去年某场考试考过的题,当时爆零了(似乎是因为没有小数据的暴力分。。

首先如果一条边的两个点在树上的路径长度为奇数,那么这条边肯定要删掉。

那么我们可以发现,这时存在偶环的充要条件就是一个环经过了任意两条非树边。

因为两个奇环通过公共边拼在一起,再把公共边挖掉,肯定是一个偶环。

所以这道题的限制就是不能出现这种情况,也就是说我们需要留下一棵仙人掌。

知道这个性质以后就不是那么难做了(虽然对于我来说还是很难

我们先把题意转化成用总边权减去最大留下的边权。

考虑一个条件,即每个点度数不超过$10$,这启发我们可以在树上维护儿子的状态。

于是考虑状压$dp$,设$f[i][S]$表示$i$这棵子树,不考虑状态$S$的集合的儿子(就是把这些儿子砍掉)的最大值。

我们考虑在$lca$处计算一条边的贡献,首先如果$lca$为$i$的所有边都不留,那么$f[i][S]=\sum f[son][S]$。

然后我们依次考虑每一条边必须加的贡献,对于每一条边,设两个端点为$a,b$(如果有一个为$lca$就把这个点丢掉)。

那么我们的贡献就是$w+f[a]+f[b]$再加上所有$a$到$b$路径上的每个点(不包括$a,b,lca$)不考虑它在路径上的儿子的状态。

很显然,这条路径不能被其他非树边覆盖,所以我们就必须把这条路径上的树边都断开,把一个点的贡献加上的时候不能考虑路径上的其他点。

所以这道题我们就做完了,复杂度为$O(m*2^{10}+mn)$。

 #include <bits/stdc++.h>
#define il inline
#define RG register
#define ll long long
#define N (2005) using namespace std; vector<int> h[N]; struct E{ int u,v,w; }e[];
struct edge{ int nt,to; }g[N<<]; int f[N][N],st[N],sz[N],fa[N],son[N],top[N],tid[N],dep[N],head[N],n,m,num,sum,tot; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return q*x;
} il void insert(RG int from,RG int to){
g[++num]=(edge){head[from],to},head[from]=num; return;
} il void dfs1(RG int x,RG int p){
fa[x]=p,sz[x]=,dep[x]=dep[p]+;
for (RG int i=head[x],v;i;i=g[i].nt){
v=g[i].to; if (v==p) continue;
dfs1(v,x),sz[x]+=sz[v];
if (sz[son[x]]<=sz[v]) son[x]=v;
}
return;
} il void dfs2(RG int x,RG int p,RG int anc){
top[x]=anc; if (son[x]) dfs2(son[x],x,anc);
for (RG int i=head[x],v;i;i=g[i].nt){
v=g[i].to; if (v!=p && v!=son[x]) dfs2(v,x,v);
}
return;
} il int lca(RG int u,RG int v){
while (top[u]!=top[v]){
if (dep[top[u]]<dep[top[v]]) swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v] ? u : v;
} il void dfs(RG int x,RG int p){
RG int tot=,sum;
for (RG int i=head[x];i;i=g[i].nt) if (g[i].to!=p) dfs(g[i].to,x);
for (RG int i=head[x];i;i=g[i].nt) if (g[i].to!=p) tid[g[i].to]=<<tot,st[tot++]=g[i].to;
for (RG int i=(<<tot)-;~i;--i){
sum=; for (RG int j=;j<tot;++j) if (!(i>>j&)) sum+=f[st[j]][]; f[x][i]=sum;
}
for (RG int i=,a=,b=,id,S=h[x].size();i<S;++i,a=b=){
id=h[x][i],sum=e[id].w;
if (e[id].u!=x) for (sum+=f[a=e[id].u][];fa[a]!=x;a=fa[a]) sum+=f[fa[a]][tid[a]];
if (e[id].v!=x) for (sum+=f[b=e[id].v][];fa[b]!=x;b=fa[b]) sum+=f[fa[b]][tid[b]];
for (RG int j=(<<tot)-;~j;--j)
if (!(j&tid[a]) && !(j&tid[b])) f[x][j]=max(f[x][j],sum+f[x][j|tid[a]|tid[b]]);
}
return;
} int main(){
#ifndef ONLINE_JUDGE
freopen("training.in","r",stdin);
freopen("training.out","w",stdout);
#endif
n=gi(),m=gi();
for (RG int i=,u,v,w;i<=m;++i){
u=gi(),v=gi(),w=gi(),sum+=w;
if (w) e[++tot]=(E){u,v,w};
if (!w) insert(u,v),insert(v,u);
}
dfs1(,),dfs2(,,);
for (RG int i=,G;i<=tot;++i){
G=lca(e[i].u,e[i].v);
if (!((dep[e[i].u]+dep[e[i].v]-(dep[G]<<))&)) h[G].push_back(i);
}
dfs(,),cout<<sum-f[][]; return ;
}

最新文章

  1. UINavigationController的创建和相关设置---学习笔记四
  2. Android 自定义Application
  3. Yocto开发笔记之《驱动调试-GPS数据采集》(QQ交流群:519230208)
  4. [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序创建更复杂的数据模型
  5. Nginx 下无法读取session 导致 thinkphp验证码错误
  6. 初探ListView
  7. JavaScript 闭包环境非常奇特 - 相当于类与实例的关系?!
  8. 解决初次使用webpack+antd-mobile时css不生效的问题
  9. uva 10391
  10. g++基本用法
  11. Java经典面试题+答案(全)
  12. 【ElasticSearch篇】--ElasticSearch从初识到安装和应用
  13. java拦截器(interceptor)
  14. 原生js学习 选择dom
  15. 移动采编app
  16. Java,JDK动态代理的原理分析
  17. CSS加DIV布局
  18. Android输出日志到电脑磁盘
  19. Perl之my与local
  20. 装饰(Decorator)模式

热门文章

  1. Angular待办事项应用4——模拟web服务
  2. PHP彻底解决mysql中文乱码
  3. K:红黑树
  4. UNIX 系统调用:dup,dup2实现重定向
  5. bzoj P4825 [Hnoi2017]单旋——solution
  6. drupal7 addExpression+union+分页
  7. DOM增删操作(创建删除表格)
  8. python学习笔记之——python模块
  9. 为什么不要使用 select * from xxx (oracle 亲测)
  10. javaEE-EJB学习笔记