点此看题面

大致题意: 给你一张图,定义\(dis(i,j)\)为\(i\)与\(j\)的最短距离,现要求删去若干条边,使得图仍然联通,且\(\sum_{i=1}^n\sum_{j=i+1}^ndis(i,j)\)最大。

一个贪心的思想

考虑到要使点与点间的距离最大,则多删边肯定是更优的。

又考虑图必须联通,则最后的图肯定是一棵树。

状压\(DP\)

看到数据范围如此之小(\(N\le14\)),自然会想到状压\(DP\)啦。

我们可以设\(f_{i,x}\)表示子集\(i\)在强制以\(x\)为根的情况下的最优解(易证此题局部最优解即为全局最优解),注意这里我们强制除根以外的节点不能向外连边。并设\(g_i\)表示子集\(i\)内的元素个数

考虑如何转移。

对于这种子集\(DP\),一般套路都是枚举\(i\)的一个子集\(j\)来将其分成\(j\)和\(i\text{^}j\)(记为\(k\))两部分。

这题也不例外。

我们可以枚举一个属于\(j\)的点\(x\),然后枚举一个属于\(k\)的点\(y\),表示将\(x\)作为根,且在\(x\)与\(y\)之间连边合并两个子集

考虑到前面我们对根的定义,则此后\(y\)的子树内的节点不可能再向外连边,即其他节点必定在靠近\(x\)的同一侧。

那我们就可以计算出这条边被经过的次数应为\(g_k*(n-g_k)\),从而得到这条边的贡献,并由此推出转移方程:

\[f_{i,x}=max(f_{i,x},f_{j,x}+f_{k,y}+g_k*(n-g_k)*v_{x,y})
\]

其中\(v_{x,y}\)表示\(x\)和\(y\)两点间的边权。

具体实现详见代码。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 14
#define M 91
#define LL long long
#define swap(x,y) (x^=y^=x^=y)
#define Gmax(x,y) (x<(y)&&(x=(y)))
#define pb push_back
using namespace std;
int n,m,g[1<<N],v[N+5][N+5];LL f[1<<N][N+5];vector<int> p[1<<N];
int main()
{
RI i,j,k,l,x,y,z,tj,tk;Reg LL ans=0;
for(scanf("%d%d",&n,&m),i=1;i<=m;++i) scanf("%d%d%d",&x,&y,&z),v[x][y]=v[y][x]=z;//读入+建边
for(l=1<<n,i=1;i^l;++i) for(g[i]=g[i>>1]+(i&1),j=1;j<=n;++j) (i>>j-1)&1&&(p[i].pb(j),f[i][j]=g[i]^1?-1:0);//初始化g数组以及f数组,用p来存储每个子集所包含的元素
for(i=1;i^l;++i) for(j=(i-1)&i;j;j=(j-1)&i)//枚举i,然后枚举它的子集j
{
for(k=i^j,tj=0;tj^g[j];++tj) if(~f[j][x=p[j][tj]]) for(tk=0;tk^g[k];++tk)//枚举一个属于j的点x和属于k的点y
if(~f[k][y=p[k][tk]]&&v[x][y]) Gmax(f[i][x],f[j][x]+f[k][y]+1LL*g[k]*(n-g[k])*v[x][y]);//判断情况是否合法后转移
}for(i=1;i<=n;++i) Gmax(ans,f[l-1][i]);//求出最优的答案
return printf("%lld",ans),0;//输出答案
}

【CCPC-Wannafly Winter Camp Day3 (Div1) D】精简改良(状压DP)的更多相关文章

  1. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  2. CCPC-Wannafly Winter Camp Day3 Div1 - 精简改良 - [生成树][状压DP]

    题目链接:https://zhixincode.com/contest/14/problem/D?problem_id=206 样例输入 1  5 5 1 2 1 1 3 1 2 4 1 2 5 1 ...

  3. Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门  Portal  原题目描述在最下面.  简单的 ...

  4. CCPC-Wannafly Winter Camp Day3 Div1 - 石头剪刀布 - [带权并查集]

    题目链接:https://zhixincode.com/contest/14/problem/I?problem_id=211 样例输入 1  3 5 2 1 1 2 1 2 1 1 2 3 2 1 ...

  5. CCPC-Wannafly Winter Camp Day3 Div1 - 排列

    题目链接:https://zhixincode.com/contest/14/problem/A?problem_id=203 time limit per test: 1 secondmemory ...

  6. 【CCPC-Wannafly Winter Camp Day3 (Div1) G】排列(水题)

    点此看题面 大致题意:已知 \(p\)为\(n\)的一个排列,定义\(A(p)_i=min_{j=1}^ip_j\),若用\(q_i\)表示\(p\)第\(i\)小的前缀的长度(以值为第一关键字,下标 ...

  7. 【CCPC-Wannafly Winter Camp Day3 (Div1) F】小清新数论(莫比乌斯反演+杜教筛)

    点此看题面 大致题意: 让你求出\(\sum_{i=1}^n\sum_{j=1}^n\mu(gcd(i,j))\). 莫比乌斯反演 这种题目,一看就是莫比乌斯反演啊!(连莫比乌斯函数都有) 关于莫比乌 ...

  8. 【CCPC-Wannafly Winter Camp Day3 (Div1) I】石头剪刀布(按秩合并并查集)

    点此看题面 大致题意: 有\(n\)个人,第\(i\)个人坐在编号为\(i\)的座位上,每个人等概率有石头.剪刀.布中的一张卡片.有两种操作:第一种是第\(y\)个人挑战第\(x\)个人,如果胜利则\ ...

  9. CCPC Wannafly Winter Camp Div2 部分题解

    Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...

随机推荐

  1. my07_lock-tables与single-transaction的区别

    概念描述 ************************************************************ mysqldump进行逻辑备份时(innodb),为保证事务的一致性 ...

  2. linux进程间的通信之 共享内存

    一.共享内存介绍 共享内存是三个IPC(Inter-Process Communication)机制中的一个. 它允许两个不相关的进程访问同一个逻辑内存. 共享内存是在两个正在进行的进程之间传递数据的 ...

  3. Django自定义过滤器

    1.首先在在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag. 2.在app中创建templatetags模块(模块名只能是temp ...

  4. (转)ping命令

    ping命令 原文:https://www.cnblogs.com/peida/archive/2013/03/06/2945407.html Linux系统的ping命令是常用的网络命令,它通常用来 ...

  5. shell 重定向 1> 2> &>

    0表示标准输入1表示标准输出2表示标准错误输出> 默认为标准输出重定向,与 1> 相同2>&1 意思是把 标准错误输出 重定向到 标准输出.&>file 意思是 ...

  6. SQLSERVER 自增列,值突然增大1000

    SQLSERVER 自增列,值突然增大1000https://blog.csdn.net/lichxi1002/article/details/40074247  

  7. Entity Framework Many to Many Relation Mapping(Entity Framework多对多关系映射)

    通常我们在做数据库设计时都会有两张表是多对多关系的时候,在数据库做多对多关系时候我们通常通过中间关联表来处理,那我们现在在EF中是如何处理的呢? 假设我们有如下关系,用户(User)包含多个角色(Ro ...

  8. MyBatis01--------概念

    主程序 读取配置 主配置文件 SQL映射文件 1.什么是框架?      ① 框架是一个应用程序的半成品      一个框架程序员可以配置的选择.选项越多,认为这款框架的可扩展性强.       面向 ...

  9. collides with another import statement解决办法

    如我要导入的两个包名为: import com.tesla.gateway.core.filter.Filter import ch.qos.logbak.core.filter.Filter 这样就 ...

  10. Hibernate课程 初探一对多映射3-3 单向多对一的测试

    public static void testManyToOne(){ Student stu1 = new Student("小明","男"); Studen ...