洛谷题目页面传送门 & 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\)的边也应该留下。于是状态转移方程就出来了:

\[dp_{i,j}=\max_{k\subseteq i-\{0,j\}}\left\{\sum_{x,y\in k\cup\{j\},(x,y,len)\in E}len+\max_{o\in i-k-\{j\},(o,j,len)\in E}\left\{len+dp_{i-k-\{j\},o}\right\}\right\}
\]

这里面有个子集枚举,所以直接按照这个方程转移是\(\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\)即可。

放一下最终的状态转移方程:

\[dp_{i,j}=\max_{k\subseteq i-\{0,j\}}\!\left\{sum_{k\cup\{j\}}+tmp_{i-k-\{j\},j}\right\}
\]

时间复杂度\(\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的更多相关文章

  1. 题解-AtCoder ARC-078F Mole and Abandoned Mine

    problem ATC-arc078F 题意概要:给定一个 \(n\) 点 \(m\) 边简单无向图(无自环无重边),边有费用,现切去若干条边,使得从 \(1\) 到 \(n\) 有且仅有一条简单路径 ...

  2. Mole and Abandoned Mine

    Mole and Abandoned Mine n点m条边的无向图,删除第i条边花费c[i],问1到n只有一条路径时所需要的最小花费? \(2\le n\le 15\) . 我又A掉了一道zzs的题啦 ...

  3. AT2657 Mole and Abandoned Mine

    传送门 好神的状压dp啊 首先考虑一个性质,删掉之后的图一定是个联通图 并且每个点最多只与保留下来的那条路径上的一个点有边相连 然后设状态:\(f[s][t]\)代表当前联通块的点的状态为\(s\)和 ...

  4. [atARC078F]Mole and Abandoned Mine

    注意到最终图的样子可以看作一条从1到$n$的路径,以及删去这条路径上的边后,路径上的每一个点所对应的一个连通块 考虑dp,令$f_{S,i}$表示当前1到$n$路径上的最后一个点以及之前点(包括$i$ ...

  5. AT2657 [ARC078D] Mole and Abandoned Mine

    简要题解如下: 记 \(1\) 到 \(n\) 的路径为关键路径. 注意到关键路径只有一条是解题的关键,可以思考这张图长什么样子. 不难发现关键路径上所有边均为桥,因此大致上是关键路径上每个点下面挂了 ...

  6. 【做题】arc078_f-Mole and Abandoned Mine——状压dp

    题意:给出一个\(n\)个结点的联通无向图,每条边都有边权.令删去一条边的费用为这条边的边权.求最小的费用以删去某些边使得结点\(1\)至结点\(n\)有且只有一条路径. \(n \leq 15\) ...

  7. AtCoder刷题记录

    构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...

  8. AtCoder Regular Contest 078

    我好菜啊,ARC注定出不了F系列.要是出了说不定就橙了. C - Splitting Pile 题意:把序列分成左右两部分,使得两边和之差最小. #include<cstdio> #inc ...

  9. 【AtCoder】ARC078

    C - Splitting Pile 枚举从哪里开始分的即可 #include <bits/stdc++.h> #define fi first #define se second #de ...

随机推荐

  1. Java连载88-HashSet集合与hashCode方法重写

    一.Set集合 1.HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构. 2.哈希表又称为散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表,每个单向链 ...

  2. opencv —— resize、pyrUp 和 pyrDown 图像金字塔(高斯金字塔、拉普拉斯金字塔)与尺寸缩放(向上采样、向下采样)

    我们经常会将某种尺寸的图像转化为其他尺寸的图像,如果需要放大或者缩小图像的尺寸,在 OpenCV 中可以使用如下两种方法: resize 函数,最直接的方法. pyrUp 和 pyrDown 函数,即 ...

  3. Qt代码区字符编码转换

    在做通讯练习的时候,发现发送给小助手字符乱码,图片如下 本人Qt Creator是UTF-8,需要改成gbk,代码如下 #include<QTextCodec> // 提供字符编码转换 Q ...

  4. Java Web 笔记(1)

    JavaWeb 学习笔记,狂神说java,链接:https://www.bilibili.com/video/av68833391 Java Web 1.基本概念 1.1.前言 web开发: web, ...

  5. Bash脚本编程学习笔记04:测试命令test、状态返回值、位置参数和特殊变量

    我自己接触Linux主要是大学学习的Turbolinux --> 根据<鸟哥的Linux私房菜:基础篇>(第三版) --> 马哥的就业班课程.给我的感觉是这些课程对于bash的 ...

  6. PS_0001:改变图片颜色 填充颜色

    1,创建新图存  ctrl + j 2,点击前景色按钮,改变颜色 3,前景色的键盘快捷键是“Alt+Delete”,背景色的键盘快捷键是“Ctrl+Delete”

  7. GitKraken 快速配置 SSH Key

    快速使用 GitKraken 配置SSH keys git是现在最流行的版本管理工具,应用范围非常广泛,推荐一款git的可视化工具,这款 工具特别方便 它的官方如下https://www.gitkra ...

  8. django cookie session 自定义分页

    cookie cookie的由来 http协议是无状态的,犹如人生若只如初见,每次都是初次.由此我们需要cookie来保持状态,保持客户端和服务端的数据通信. 什么是cookie Cookie具体指的 ...

  9. vue动画&过渡整理

  10. 小程序texarea 输入内容回显失败

    原因:输入框是textarea,输入的数据是含有换行符的字符串,小程序能渲染这种数据的标签有text,和textarea.(view 标签不能识别 /n 等字符) 1.使用text失败是由于不能覆盖视 ...