[atARC078F]Mole and Abandoned Mine
注意到最终图的样子可以看作一条从1到$n$的路径,以及删去这条路径上的边后,路径上的每一个点所对应的一个连通块
考虑dp,令$f_{S,i}$表示当前1到$n$路径上的最后一个点以及之前点(包括$i$)所对应连通块的并,转移考虑枚举下一个点以及其对应的连通块,即$f_{S\cup T,j}=\min(f_{S,i}+sum(S,T)-len(i,j))$
(其中$len(i,j)$表示$(i,j)$这条边的长度,$sum(S,T)=\sum_{x\in S,y\in T,(x,y)\in E}len(x,y)$)
初始状态为$f_{S,1}=0$(其中$1\in S$且$S$的导出子图连通),$f_{other}=\infty$
转移条件为$(i,j)\in E$、$j\in T$、$S\cap T=\empty$且$T$的导出子图连通,因此转移复杂度为$o(n^{2}3^{n})$(关于$T$导出子图连通的这个条件预处理即可)
进一步优化,关于$j$和$T$的枚举可以分开,即先求出$g_{j}=\min(f_{S,i}-len(i,j))$,再枚举包含$j$的$T$即可(这样做的实际意义是先将$S$中所有到$j$的边选择最小的),时间复杂度降为$o(n3^{n})$


1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 15
4 struct ji{
5 int nex,to,len;
6 }edge[N*N];
7 int E,n,m,x,y,z,head[N],vis[N],g[N],con[1<<N],sum[1<<N],f[1<<N][N];
8 void add(int x,int y,int z){
9 edge[E].nex=head[x];
10 edge[E].to=y;
11 edge[E].len=z;
12 head[x]=E++;
13 }
14 void dfs(int k,int s){
15 if (((s&(1<<k))==0)||(vis[k]))return;
16 vis[k]=1;
17 for(int i=head[k];i!=-1;i=edge[i].nex)dfs(edge[i].to,s);
18 }
19 int main(){
20 scanf("%d%d",&n,&m);
21 memset(head,-1,sizeof(head));
22 for(int i=1;i<=m;i++){
23 scanf("%d%d%d",&x,&y,&z);
24 add(x-1,y-1,z);
25 add(y-1,x-1,z);
26 }
27 memset(f,0x3f,sizeof(f));
28 for(int i=0;i<(1<<n);i++){
29 memset(vis,0,sizeof(vis));
30 for(int j=0;j<n;j++)
31 if (i&(1<<j)){
32 dfs(j,i);
33 break;
34 }
35 bool flag=0;
36 for(int j=0;j<n;j++)
37 if ((i&(1<<j))&&(!vis[j])){
38 flag=1;
39 break;
40 }
41 if (!flag){
42 con[i]=1;
43 if (i&1)f[i][0]=0;
44 }
45 }
46 for(int i=1;i<(1<<n);i+=2){
47 if (!con[i])continue;
48 for(int x=0;x<n;x++){
49 g[x]=0x3f3f3f3f;
50 sum[(1<<x)]=0;
51 }
52 for(int x=0;x<n;x++)
53 if ((i&(1<<x))){
54 for(int j=head[x];j!=-1;j=edge[j].nex){
55 y=edge[j].to;
56 if ((i&(1<<y))==0){
57 g[y]=min(g[y],f[i][x]-edge[j].len);
58 sum[(1<<y)]+=edge[j].len;
59 }
60 }
61 }
62 int ii=(1<<n)-1-i;
63 for(int j=(ii&(ii-1));j>=0;j=((j-1)&ii)){
64 int jj=(ii^j),k=(jj&(jj-1));
65 sum[jj]=sum[jj^k]+sum[k];
66 if (jj==ii)break;
67 }
68 for(int x=0;x<n;x++)
69 for(int j=ii;j;j=((j-1)&ii))
70 if ((j&(1<<x))&&(con[j]))f[i|j][x]=min(f[i|j][x],g[x]+sum[j]);
71 }
72 printf("%d",f[(1<<n)-1][n-1]);
73 }
[atARC078F]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的题啦 ...
- AT2657 Mole and Abandoned Mine
传送门 好神的状压dp啊 首先考虑一个性质,删掉之后的图一定是个联通图 并且每个点最多只与保留下来的那条路径上的一个点有边相连 然后设状态:\(f[s][t]\)代表当前联通块的点的状态为\(s\)和 ...
- 题解-AtCoder ARC-078F Mole and Abandoned Mine
problem ATC-arc078F 题意概要:给定一个 \(n\) 点 \(m\) 边简单无向图(无自环无重边),边有费用,现切去若干条边,使得从 \(1\) 到 \(n\) 有且仅有一条简单路径 ...
- 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\) 的路径为关键路径. 注意到关键路径只有一条是解题的关键,可以思考这张图长什么样子. 不难发现关键路径上所有边均为桥,因此大致上是关键路径上每个点下面挂了 ...
- 【做题】arc078_f-Mole and Abandoned Mine——状压dp
题意:给出一个\(n\)个结点的联通无向图,每条边都有边权.令删去一条边的费用为这条边的边权.求最小的费用以删去某些边使得结点\(1\)至结点\(n\)有且只有一条路径. \(n \leq 15\) ...
- 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 ...
- AtCoder刷题记录
构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...
随机推荐
- Git学习笔记02-配置
安装好Git之后,做的就是需要配置Git了 第一步,配置自己的名称和邮箱 打开Git Bash 输入命令 git config --global user.name "用户名" g ...
- 接口自动化-Python3+request上传文件,发送multipart/form-data编码
1.安装requests_toolbelt pip install requests-toolbelt 2.发送文件中的数据 from requests_toolbelt import Multi ...
- CompleteFuture实现简单的任务编排实践
CompleteFuture实现简单的任务编排实践 一:前言 CompleteFuture是java8 新提供的API,是对函数式编程思想的体现,提供了很多的对于函数式编程支持.不止有同步处理功能 ...
- PAT (Basic Level) Practice (中文)1076 Wifi密码 (15分)
1076 Wifi密码 (15分) 下面是微博上流传的一张照片:"各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1:B- ...
- 【JAVA】【作业向】第一题:本学期一班级有n名学生,m门课程。现要求对每门课程的成绩进行统计:平均成绩、最高成绩、最低成绩,并统计考试成绩的分布律。
1.预备知识:动态数组Array实现: 2.解题过程需要理解的知识:吧唧吧唧吧唧吧唧 不想做了 就用了最简单的方法 和c语言类似 java版本 `import java.util.Scanner; / ...
- 单片机STM32的5个时钟源知识
众所周知STM32有5个时钟源HSI.HSE.LSI.LSE.PLL,其实他只有四个,因为从上图中可以看到PLL都是由HSI或HSE提供的. 其中,高速时钟(HSE和HSI)提供给芯片主体的主时钟.低 ...
- Linux内核漏洞精准检测如何做?SCA工具不能只在软件层面
摘要:二进制SCA工具要想更好的辅助安全人员实现安全审计.降低漏洞检测的误报率,必须向更细颗粒度的检测维度发展,而不仅仅停留在开源软件的层面,同时对漏洞库的要求也需要向细颗粒度的精准信息提出的挑战. ...
- 洛谷 P3209 [HNOI2010] 平面图判定
链接: P3209 题意: 给出 \(T\) 张无向图 \((T\leq100)\),并给出它对应的哈密顿回路,判断每张图是否是平面图. 分析: 平面图判定问题貌似是有线性做法的,这里给出链接,不是本 ...
- linux中的strip命令简介
转载:https://blog.csdn.net/qq_37858386/article/details/78559490 strip:去除,剥去 一.下面是man strip获得到的信息,简 ...
- vector之erase和迭代器
C++开发中使用vector时非常方便的,但是也是需要非常小心的,最近在使用容器删除某个元素的时候,测试结果出现了异常 /* vector erase test*/ int testVector() ...