题解-AtCoder ARC-078F Mole and Abandoned Mine
problem
题意概要:给定一个 \(n\) 点 \(m\) 边简单无向图(无自环无重边),边有费用,现切去若干条边,使得从 \(1\) 到 \(n\) 有且仅有一条简单路径,求最小化花费。
\(n\le 15, n-1\le m\le \binom n2\)
Solution
看到 \(n\leq 15\) 大概就能猜到复杂度是 \(O(3^n)\) 左右的,然后直接思考用斯坦纳树咋解,无果。
开始思考最终局面的情况,一定是有一条 \(1\) 到 \(n\) 的路径,且不能存在其他路径连接这条路径上的两个点。换句话说,就是从每个点出发且只走非路径边的话只能到达一个路径上的点。
考虑原问题要求最小化删边费用,对应上面的做法容易想到要转换为最大化留下来的边权和
把图画出来,大概是说路径上每个点下头都挂上了若干个集合,而由于要最大化比边权和,所以每个集合内部的所有边均予以保留。
那么就很容易得到一个dp:设 \(f[i][S]\) 表示在路径(最终连接 \(1\) 和 \(n\) 的路径)上走到了 \(i\),并且集合 \(S\) 内的点已经挂在了前头,那么有两种转移:
- 在路径上更进一步:\(f[i][S] \rightarrow f[j][S\cup \{j\}]\),增加权值为连接 \(i,j\) 的边权
- 在当前点挂一个集合:\(f[i][S]\rightarrow f[i][S\cup T]\),增加权值为集合 \(T\) 内所有边的边权和
那么只要预处理一个 \(g[S]\) 表示集合 \(S\) 内的边权和,这一步可以暴力求,复杂度 \(O(2^nn^2)\)
再进行转移,转移时需要枚举子集(对于全局而言,枚举补集的子集和枚举子集复杂度相当),复杂度 \(O(n3^n)\)
总复杂度 \(O(2^nn^2+n3^n)\)
Code
#include <cstdio>
#define bin(x) (1<<(x))
#define b(x) (1<<(x)>>1)
inline void cmax(int&x, const int y) {x < y && (x = y);}
const int N = 17, M = 40100;
int f[N][M], g[M];
int mp[N][N];
int n, m;
int main() {
scanf("%d%d",&n,&m); int Ans = 0;
for(int i=1,x,y,z;i<=m;++i) {
scanf("%d%d%d",&x,&y,&z), Ans += z;
mp[x][y] = mp[y][x] = z;
}
for(int s=0;s<bin(n);++s) {
int&v = g[s];
for(int i=1;i<=n;++i) if(s & b(i))
for(int j=i+1;j<=n;++j) if(s & b(j)) v += mp[i][j];
}
for(int i=1;i<=n;++i)
for(int j=0;j<bin(n);++j)
f[i][j] = -1;
f[1][1] = 0;
for(int S=1;S<bin(n);++S)
for(int i=1;i<=n;++i) if((S & b(i)) and ~f[i][S]) {
for(int j=1;j<=n;++j) if((~S & b(j)) and mp[i][j]) cmax(f[j][S|b(j)], f[i][S] + mp[i][j]);
for(int iS=(bin(n)-1)^S, s = iS; s; s = (s-1) & iS)
cmax(f[i][S|s], f[i][S] + g[s|b(i)]);
}
printf("%d\n", Ans - f[n][bin(n)-1]);
return 0;
}
题解-AtCoder ARC-078F Mole and Abandoned Mine的更多相关文章
- Mole and Abandoned Mine
Mole and Abandoned Mine n点m条边的无向图,删除第i条边花费c[i],问1到n只有一条路径时所需要的最小花费? \(2\le n\le 15\) . 我又A掉了一道zzs的题啦 ...
- AtCoder arc078_d Mole and Abandoned Mine
洛谷题目页面传送门 & AtCoder题目页面传送门 给定一个无向连通带权图\(G=(V,E),|V|=n,|E|=m\)(节点从\(0\)开始编号),要删掉一些边使得节点\(0\)到\(n- ...
- AT2657 [ARC078D] Mole and Abandoned Mine
简要题解如下: 记 \(1\) 到 \(n\) 的路径为关键路径. 注意到关键路径只有一条是解题的关键,可以思考这张图长什么样子. 不难发现关键路径上所有边均为桥,因此大致上是关键路径上每个点下面挂了 ...
- [题解] Atcoder ARC 142 D Deterministic Placing 结论,DP
题目 (可能有点长,但是请耐心看完,个人认为比官方题解好懂:P) 首先需要注意,对于任意节点i上的一个棋子,如果在一种走法中它走到了节点j,另一种走法中它走到了节点k,那么这两种走法进行完后,棋子占据 ...
- AT2657 Mole and Abandoned Mine
传送门 好神的状压dp啊 首先考虑一个性质,删掉之后的图一定是个联通图 并且每个点最多只与保留下来的那条路径上的一个点有边相连 然后设状态:\(f[s][t]\)代表当前联通块的点的状态为\(s\)和 ...
- [atARC078F]Mole and Abandoned Mine
注意到最终图的样子可以看作一条从1到$n$的路径,以及删去这条路径上的边后,路径上的每一个点所对应的一个连通块 考虑dp,令$f_{S,i}$表示当前1到$n$路径上的最后一个点以及之前点(包括$i$ ...
- [题解] Atcoder ARC 142 E Pairing Wizards 最小割
题目 建图很妙,不会. 考虑每一对要求合法的巫师(x,y),他们两个的\(a\)必须都大于\(min(b_x,b_y)\).所以在输入的时候,如果\(a_x\)或者\(a_y\)小于\(min(b_x ...
- [题解] Atcoder Regular Contest ARC 147 A B C D E 题解
点我看题 A - Max Mod Min 非常诈骗.一开始以为要观察什么神奇的性质,后来发现直接模拟就行了.可以证明总操作次数是\(O(nlog a_i)\)的.具体就是,每次操作都会有一个数a被b取 ...
- 【题解】Atcoder ARC#96 F-Sweet Alchemy
首先,我们发现每一个节点所选择的次数不好直接算,因为要求一个节点被选择的次数大于等于父亲被选择的次数,且又要小于等于父亲被选择的次数 \(+D\).既然如此,考虑一棵差分的树,规定每一个节点被选择的次 ...
随机推荐
- Android Mboot mmc命令介绍
mmc command. 目前Mboot支持以下mmc命令: 1) mmc read/write. 读写命令.Addr = 内存地址, blk# = 起始block数, size ...
- Linux 打开文件数
linux设置最大打开文件数 - daiyudong2020的博客 - CSDN博客 https://blog.csdn.net/daiyudong2020/article/details/77828 ...
- 使用log4j将日志输送到控制台、文件或数据库中
转: 使用log4j将日志输送到控制台.文件或数据库中 2018-09-07 00:45:08 keep@ 阅读数 2880更多 分类专栏: 其它 版权声明:本文为博主原创文章,遵循CC 4.0 ...
- Labelme数据转mask_rcnn数据格式
labelme数据转mask_rcnn数据格式 # coding: utf-8 import argparse import json import os import os.path as osp ...
- DataWorks2.0——DataStudio简单对比使用上手
1.原先的数据管理去哪里了? 悬停在此图标上即可: 2.项目模式有何不同?
- 定时备份删除数据库sql
1.备份数据库 mkdir -p /home/mysql/mysql_bak/ vi mysql_bak.sh #!/bin/bash #Shell Command For Backup MySQL ...
- Oracle 自动生成的视图VM_NSO_1
作者:Jerry 有时候优化sql的时候,在执行计划中看到有VM_NSO_X的视图,在Oracle定义中,可以吧NSO理解为nested subquery optimizing,功能就是把in转换为j ...
- websehll的使用和预防措施
(1).webshell概念 webshell就是以asp.php.jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门.黑客在入侵了一个网站后,通常会将asp或php后 ...
- JAVA视频压缩
https://www.cnblogs.com/chuanyueinlife/p/9014627.html
- chrome浏览器调试JS代码
是怎么调试 JavaScript 程序的?最原始的方法是用 alert() 在页面上打印内容,稍微改进一点的方法是用 console.log() 在 JavaScript 控制台上输出内容.嗯~,用这 ...