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 ...
随机推荐
- python基础入门之三 —— 字符串
1.格式 一对引号和三对引号可以表示字符串 (三引号保留换行) 2.下标 从0开始循序向下分配 str1='abcdefg' print(str1) print(str1[0]) print(str1 ...
- MSSQL sqlserver 统计"一个字符串"在"另一个字符串"中出现的次数的方法
转自 http://www.maomao365.com/?p=9858 摘要: 下文讲述sqlserver中最快获取一个字符串在另一个字符串中出现个数的方法分享 实验环境:sql server 20 ...
- ext4文件系统启动自检的必要性
最近我们发现多个用户设备掉电后重启,系统不工作. 研究这些返修设备,发现这些设备的表象是网络连接失败,DNS resolve不了.进一步发现/etc/resolv.conf为空,所以应用程序没法进行D ...
- 清北学堂—2020.1提高储备营—Day 3(图论初步(一))
qbxt Day 3 --2020.1.19 济南 主讲:李奥 目录一览 1.图论(图.图的存储方式.最小生成树的定义) 总知识点:图论 前言:众所周知,图论是一个非常重要的部分,而这次集训也可以算从 ...
- 吴裕雄--天生自然HADOOP操作实验学习笔记:分布式及RPC通信简介
实验目的 掌握GOF设计模式的代理模式 了解掌握socket编程.java反射.动态代理 了解NIO.多线程 掌握hadoop的RPC框架使用API 实验原理 1.什么是RPC 在hadoop出现以前 ...
- Page Visibility API
在code review时看见同事使用visibilitychange 事件来监听页面的隐藏与显示,之前没有了解过这块,学习一下. document.visibilityState 主要有以下3个状态 ...
- Codeforces Round #622(Div 2)C2. Skyscrapers (hard version)
题目链接 : C2. Skyscrapers (hard version) 题目描述 : 与上一道题类似,只是数据范围变大, 5e5, 如果用我们原来的方法,铁定是超时的. 考察点 : 单调栈,贪心, ...
- BZOJ#2121. 字符串游戏 [区间dp]
// powered by c++11 // by Isaunoya #include<bits/stdc++.h> #define rep(i , x , y) for(register ...
- jquery form表单赋值封装
;!(function ($) { $.fn.setFormValue = function (options) { var $this = $(this); $.each(options, func ...
- 曼孚科技:AI语音交互领域常用的4个术语
语音交互是基于语音输入的新一代交互模式,比较典型的应用场景是各类语音助手. 本文整理了语音交互领域常用的4个术语,希望可以帮助大家更好地理解这门学科. 1. 语音合成标记语言(SSML) 语音合成标 ...