AtCoder arc078_d Mole and Abandoned Mine
洛谷题目页面传送门 & AtCoder题目页面传送门
给定一个无向连通带权图\(G=(V,E),|V|=n,|E|=m\)(节点从\(0\)开始编号),要删掉一些边使得节点\(0\)到\(n-1\)有且只有\(1\)条简单路径,求最小的删掉的边的权值和。
\(n\in[2,15],m\in\left[n-1,\dfrac{n(n-1)}2\right]\),\(G\)中没有重边或自环。
这个问题显然可以转化为:求最大的删过边之后的图的边权和,再用原图的边权和减去它。
考率删过边之后的图\(G'(V,E')\)的样子。\(0\to n-1\)只有\(1\)条简单路径,设它为\(pa\left(pa_1=0,pa_s=n-1,\forall i\in[1,s),(pa_i,pa_{i+1},len)\in E'\right)\)。若\(\exists i\in[1,s],\exists j\in[i+1,s]\),\(pa_i\to pa_j\)有不止\(1\)条简单路径,那么显然可以先走\(0\to pa_i\),然后分别走\(pa_i\to pa_j\)的多条路径,最后走\(pa_j\to n-1\),构造出多条\(0\to n-1\)路径,不符合题意。可以得到\(\forall i\in[1,s],\forall j\in[i+1,s]\),\(pa_i\to pa_j\)只有\(1\)条简单路径。所以\(G'\)应该是这样的:\(pa\)中每个点下面挂着几坨连通的点,各个点挂的点集没有交集(如果有交集,那么这\(2\)个\(pa\)中的点之间的简单路径就会不止\(1\)条)。
最优情况下,\(G'\)一定是连通的。理由:若\(G'\)不连通,由于\(G'\)合法,\(0,n-1\)一定在一个连通分量内。那么可以在除了\(0,n-1\)所在连通分量的其他连通分量之间恢复若干被删除的边使得它们连通(由于原图\(G\)连通,一定可行)。此时\(G'\)还剩\(2\)个连通分量,设它们分别为\(A,B\),其中\(0,n-1\in A\)。由于原图\(G\)连通,一定可以找到一组点\((a,b)\)使得\(a\in A,b\in B,(a,b,len)\in E\),将\((a,b,len)\)恢复,这样\(B\)就成为了挂在\(pa\)中点下新的一坨点或某坨旧点的一份子。如此,可以在\(G'\)上恢复若干被删除的边,使得它更优且合法。所以最优情况下,\(G'\)一定是连通的。
接下来,利用任意\(2\)坨点都没有交集这个性质,就可以状压DP了。设\(dp_{i,j}(0\in i)\)表示\(pa\)中\(0\to j\)这条链包括它们下面挂的那些坨点所构成的点集为bitmask\(i\)时,\(\left\{(x,y,len)\mid x,y\in i,(x,y,len)\in E\right\}\)中可以留下的边的最大权值和。显然,目标为\(\sum\limits_{(x,y,len)\in E}len-dp_{V,n-1}\),边界为\(dp_{i,0}=\sum\limits_{x,y\in i,(x,y,len)\in E}len\)。转移时,枚举\(j\)下挂的点集,这个点集和\(\{j\}\)的并集中显然应该所有的边都留下,再枚举\(pa\)中\(j\)的前一个点,这个点到\(j\)的边也应该留下。于是状态转移方程就出来了:
\]
这里面有个子集枚举,所以直接按照这个方程转移是\(\mathrm O\!\left(3^nn^3\right)\)的,过不去。显然,可以预处理出\(sum_i=\sum\limits_{x,y\in i,(x,y,len)\in E}len\),复杂度降到了\(\mathrm O\!\left(3^nn^2\right)\),但还是过不去。接下来要处理\(\max\limits_{o\in i-k-\{j\},(o,j,len)\in E}\left\{len+dp_{i-k-\{j\},o}\right\}\),不难发现这个式子仅关于\(i-k-\{j\}\)和\(j\),而不同的二元组\((i-k-\{j\},j)\)只有\(\mathrm O(2^nn)\)个,这个式子却被计算了\(\mathrm O(3^nn)\)次。于是我们可以避免重复计算,记录\(tmp_{i,j}=\max\limits_{k\in i,(k,j,len)\in E}\left\{len+dp_{i,k}\right\}\),在每次完成一个\(dp_{i,j}\)的计算时,更新所有与它相关的\(tmp\)的值,即令\(\forall k\notin i((j,k,len)\in E),tmp_{i,k}=\max(tmp_{i,k},len+dp_{i,j})\)。这样,在状态转移方程中遇到这个式子时,直接调用\(tmp\)即可。
放一下最终的状态转移方程:
\]
时间复杂度\(\mathrm O\!\left(3^nn+2^nn^2\right)=\mathrm O(3^nn)\)。
最后上代码:
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=15;
int n,m;
int tb[N][N];//邻接矩阵
int sum[1<<N];
int tmp[1<<N][N],dp[1<<N][N];
void prt_bitmsk(int x){
for(int i=0;i<n;i++)cout<<!!(x&1<<i);
}
int main(){
cin>>n>>m;
int tot=0;
while(m--){
int x,y,z;
cin>>x>>y>>z;
x--;y--;
tb[x][y]=tb[y][x]=z;
tot+=z;
}
for(int i=0;i<1<<n;i++){//预处理sum
for(int j=0;j<n;j++)if(i&1<<j)for(int k=j+1;k<n;k++)if(i&1<<k)
sum[i]+=tb[j][k];
// printf("sum[");prt_bitmsk(i);printf("]=%d\n",sum[i]);
}
for(int i=0;i<1<<n;i++)for(int j=0;j<n;j++)dp[i][j]=tmp[i][j]=-inf;//初始化
for(int i=0;i<1<<n;i++)if(i&1)for(int j=0;j<n;j++)if(i&1<<j){//DP
if(j)//非边界
for(int k=i^1<<j^1;;k=k-1&(i^1<<j^1)){//枚举j下面挂的点集k
dp[i][j]=max(dp[i][j],sum[k|1<<j]+tmp[i^k^1<<j][j]);//状态转移方程
if(!k)break;
}
else//边界
dp[i][j]=sum[i];
// printf("dp[");prt_bitmsk(i);printf("][%d]=%d\n",j,dp[i][j]);
for(int k=0;k<n;k++)if(!(i&1<<k))//更新与dp[i][j]有关的所有tmp[i][k]
if(tb[j][k])
tmp[i][k]=max(tmp[i][k],dp[i][j]+tb[j][k]);
}
cout<<tot-dp[(1<<n)-1][n-1];//目标
return 0;
}
AtCoder arc078_d Mole and Abandoned Mine的更多相关文章
- 题解-AtCoder ARC-078F Mole and Abandoned Mine
problem ATC-arc078F 题意概要:给定一个 \(n\) 点 \(m\) 边简单无向图(无自环无重边),边有费用,现切去若干条边,使得从 \(1\) 到 \(n\) 有且仅有一条简单路径 ...
- Mole and Abandoned Mine
Mole and Abandoned Mine n点m条边的无向图,删除第i条边花费c[i],问1到n只有一条路径时所需要的最小花费? \(2\le n\le 15\) . 我又A掉了一道zzs的题啦 ...
- AT2657 Mole and Abandoned Mine
传送门 好神的状压dp啊 首先考虑一个性质,删掉之后的图一定是个联通图 并且每个点最多只与保留下来的那条路径上的一个点有边相连 然后设状态:\(f[s][t]\)代表当前联通块的点的状态为\(s\)和 ...
- [atARC078F]Mole and Abandoned Mine
注意到最终图的样子可以看作一条从1到$n$的路径,以及删去这条路径上的边后,路径上的每一个点所对应的一个连通块 考虑dp,令$f_{S,i}$表示当前1到$n$路径上的最后一个点以及之前点(包括$i$ ...
- AT2657 [ARC078D] Mole and Abandoned Mine
简要题解如下: 记 \(1\) 到 \(n\) 的路径为关键路径. 注意到关键路径只有一条是解题的关键,可以思考这张图长什么样子. 不难发现关键路径上所有边均为桥,因此大致上是关键路径上每个点下面挂了 ...
- 【做题】arc078_f-Mole and Abandoned Mine——状压dp
题意:给出一个\(n\)个结点的联通无向图,每条边都有边权.令删去一条边的费用为这条边的边权.求最小的费用以删去某些边使得结点\(1\)至结点\(n\)有且只有一条路径. \(n \leq 15\) ...
- AtCoder刷题记录
构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...
- AtCoder Regular Contest 078
我好菜啊,ARC注定出不了F系列.要是出了说不定就橙了. C - Splitting Pile 题意:把序列分成左右两部分,使得两边和之差最小. #include<cstdio> #inc ...
- 【AtCoder】ARC078
C - Splitting Pile 枚举从哪里开始分的即可 #include <bits/stdc++.h> #define fi first #define se second #de ...
随机推荐
- #《Essential C++》读书笔记# 第三章 泛型编程风格
基础知识 array与vector是连续存储空间,可以用指针的算术运算实现对容器的访问.list也是一个容器,不同的是,list的元素以一组指针相互链接(linked):前向(forward)指针指向 ...
- 电信IOT平台固件升级
1 离线签名 注意事项:特别重要,被坑了好久 A 将差分文件.bin格式的压缩成.zip 再进行签名 B 不能再中文目录下 否则,会出现校验失败 记住私钥 2 上传公钥 3 上传固件包 4 ...
- [Python]爬取 游民星空网站 每周精选壁纸(1080高清壁纸) 网络爬虫
一.检查 首先进入该网站的https://www.gamersky.com/robots.txt页面 给出提示: 弹出错误页面 注: 网络爬虫:自动或人工识别robots.txt,再进行内容爬取 约束 ...
- mybatis_day02
2.映射器Mapper 相当于dao层,不用写实现类(mybatis底层会采用动态代理模式 会跟我生成实现) 步骤: (1) 创建项目 配置mybatis-config.xml 和昨天一样 (2) 创 ...
- P2256 一中校运会之百米跑
----------------------- 题目链接:MIKU --------------------- 我现在发现找BUG的最好方法————喝水 喝一次找一个,喝两次A道题 --------- ...
- 安装JumpServer到CentOS(YUM)
运行环境 系统版本:CentOS Linux release 7.6.1810 (Core) 软件版本:JumpServer-1.4.8 硬件要求:最低2核4GB 官方文档:https://docs. ...
- Redis入门-01
目录 使用场景 支持的数据类型 主从复制 原理 配置 哨兵机制 持久化 RDB(Redis Database) AOF(Append Only File) redis(Remote DIctionar ...
- 关于form表单提交数据后不跳转页面+ajax接收返回值的处理
1.前台的form表单建立,注意action.enctype的内容, 2.通过添加一个隐藏的iframe标签使form的target指向iframe来达到不跳转页面的效果,同时需要在js里获取ifra ...
- Html5学习系列
Html5学习系列 HTML5 规定了一种通过 video 元素来包含视频的标准方法 Ogg = 带有 Theora 视频编码和 Vorbis 音频编码的 Ogg 文件 MPEG4 = 带有 H.26 ...
- javascript 权威指南一
1. JavaScript是面向web(网页)的编程语言. 2.html: 描述网页内容,css:描述网页样式,JavaScript:描述网页行为 3.JavaScript非常适合面向对象和函数式的编 ...