(状压dp)ABC 067 F : Mole and Abandoned Mine

Mole decided to live in an abandoned mine. The structure of the mine is represented by a simple connected undirected graph which consists of N vertices numbered 1through N and M edges. The i-th edge connects Vertices ai and bi, and it costs ciyen (the currency of Japan) to remove it.

Mole would like to remove some of the edges so that there is exactly one path from Vertex 1 to Vertex N that does not visit the same vertex more than once. Find the minimum budget needed to achieve this.

Constraints

  • 2≤N≤15
  • N?1≤MN(N?1)?2
  • 1≤ai,biN
  • 1≤ci≤106
  • There are neither multiple edges nor self-loops in the given graph.
  • The given graph is connected.

Input

Input is given from Standard Input in the following format:

N M
a1 b1 c1
:
aM bM cM

Output

Print the answer.

Sample Input 1

4 6
1 2 100
3 1 100
2 4 100
4 3 100
1 4 100
3 2 100

Sample Output 1

200

By removing the two edges represented by the red dotted lines in the figure below, the objective can be achieved for a cost of 200 yen.

Sample Input 2

2 1
1 2 1

Sample Output 2

0

It is possible that there is already only one path from Vertex 1 to Vertex N in the beginning.

Sample Input 3

15 22
8 13 33418
14 15 55849
7 10 15207
4 6 64328
6 9 86902
15 7 46978
8 14 53526
1 2 8720
14 12 37748
8 3 61543
6 5 32425
4 11 20932
3 12 55123
8 2 45333
9 12 77796
3 9 71922
12 15 70793
2 4 25485
11 6 1436
2 7 81563
7 11 97843
3 1 40491

Sample Output 3

133677

同时进行两种递推:1、加入单独1点 2、加入一与当前无交集的点集    get: line50 如何取得补集的所有子集。
 1 #include <bits/stdc++.h>
 2 typedef long long ll;
 3 using namespace std;
 4 const int MAX=1e5+5;
 5 const int INF=1e9;
 6 int n,m;
 7 int edge[20][20];
 8 int total;
 9 int cost[1<<16][16],dp[1<<16][16];//dp[s][x]记录达到某点集s,最后“末端”(继续连接其余点的唯一点)为x时余下权值和最大的边的情况
10 int inner[1<<16];//内部的边
11 int main()
12 {
13     scanf("%d%d",&n,&m);
14     for(int i=1;i<=m;i++)//读入数据
15     {
16         int x,y,price;
17         scanf("%d%d%d",&x,&y,&price);
18         --x;--y;
19         edge[x][y]=edge[y][x]=price;
20     }
21     total=1<<n;
22     for(int i=0;i<total;i++)//计算某点集内部所有边权值之和
23         for(int a=0;a<n;a++)
24             if(i&(1<<a))
25                 for(int b=0;b<a;b++)
26                     if(i&(1<<b))
27                         if(edge[a][b])
28                             inner[i]+=edge[a][b];
29     for(int i=0;i<total;i++)//计算某点集到点集外某点所有边的权值之和
30         for(int a=0;a<n;a++)
31             if(!(i&(1<<a)))
32                 for(int b=0;b<n;b++)
33                     if((i&(1<<b))&&edge[a][b])
34                         cost[i][a]+=edge[a][b];
35     memset(dp,-1,sizeof(dp));
36     dp[1][0]=0;//只有1个点的集合dp值显然为0
37     for(int i=0;i<total;i++)
38     {
39
40         for(int a=0;a<n;a++)
41         {
42             if((i&(1<<a))&&dp[i][a]!=-1)
43             {
44                 for(int b=0;b<n;b++)
45                     if(!(i&(1<<b)))/*只加入一个点*/
46                         if(edge[a][b])
47                             dp[i|(1<<b)][b]=max(dp[i|(1<<b)][b],dp[i][a]+edge[a][b]);
48                 /*加入一个点集*/
49                 int left=total-1-i;
50                 for(int now=left;now!=0;now=(now-1)&left)//用此循环得到所有
51                 {
52                     int num=inner[now]+cost[now][a];
53                     dp[i|now][a]=max(dp[i|now][a],dp[i][a]+num);
54                 }
55             }
56         }
57     }
58     printf("%d\n",inner[total-1]-dp[total-1][n-1]);
59     return 0;
60 }
时间: 2024-11-01 21:01:31

(状压dp)ABC 067 F : Mole and Abandoned Mine的相关文章

【Foreign】Number [状压DP]

Number Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 12345 5 Sample Output 24 HINT Solution 我们运用状压DP,令 f[j][opt] 表示当前余数为 j,状态为opt的方案. 状态记录的是:各个数字被用了几次. 那么我们就可以状压了.先DFS出每个状态,记sum[k]表示后缀积,那么显然 从 opt 转移到 第k个数字多用一次的状态 就是

codevs2596 售货员的难题(状压dp)

2596 售货员的难题 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 钻石 Diamond 题目描述 Description 某乡有n个村庄(1<n<=15),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)是已知的,且A村到B村与B村到A村的路大多不同.为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为1,他不知道选择什么样的路线才能使所走的路程最短.请你帮他选择一条最短的路. 输入描述 Input D

【状压dp】【bzoj 1087】【SCOI 2005】互不侵犯King

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1991 Solved: 1185 Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数. Sa

【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理

题目描述 求一张有向图的强连通生成子图的数目对 $10^9+7$ 取模的结果. 题解 状压dp+容斥原理 设 $f[i]$ 表示点集 $i$ 强连通生成子图的数目,容易想到使用总方案数 $2^{sum[i]}$ 减去不为强连通图的方案数得到强连通图的方案数,其中 $sum[i]$ 表示点集 $i$ 中边的数目. 考虑什么样的图不是强连通图:缩点后入度为0的强连通分量对应的点集不是全集. 枚举这些入度为0的强连通分量对应的点集,由于无法保证只有这些点构成的入度为0的强连通分量,因此需要进一步容斥.

[bzoj3717][PA2014]Pakowanie_动态规划_状压dp

Pakowanie bzoj-3717 PA-2014 题目大意:给你n个物品m个包,物品有体积包有容量,问装下这些物品最少用几个包. 注释:$1\le n\le 24$,$1\le m\le 100$ 想法:以为是什么超级牛逼的背包dp,结果就是状压dp 状态:f[s]表示装s状态的物品需要多少背包,g[s]表示在f[s]的前提下,最大的背包剩余的容量. 转移:直接判断最后一个能不能装下当前物品,转移即可. 还有就是这个题卡常,只能直接用Lowbit枚举1,不能全枚举,会T... ... 最后

Luogu4221 WC2018州区划分(状压dp+FWT)

合法条件为所有划分出的子图均不存在欧拉回路或不连通,也即至少存在一个度数为奇数的点或不连通.显然可以对每个点集预处理是否合法,然后就不用管这个奇怪的条件了. 考虑状压dp.设f[S]为S集合所有划分方案的满意度之和,枚举子集转移,则有f[S]=Σg[S']*f[S^S']*(sum[S']/sum[S])p (S'?S),其中g[S]为S集合是否合法,sum[S]为S集合人口数之和.复杂度O(3n).这个式子非常显然,就这么送了50分.p这么小显得非常奇怪但也没有任何卵用. 考虑优化.转移方程写

Codeforces Round #531 (Div. 3) F. Elongated Matrix(状压DP)

F. Elongated Matrix 题目链接:https://codeforces.com/contest/1102/problem/F 题意: 给出一个n*m的矩阵,现在可以随意交换任意的两行,最后从上到下,从左到右形成一个序列s1,s2.....snm,满足对于任意相邻的两个数,它们差的绝对值的最大值为k. 现在问怎么交换行与行,可以使得最后的这个k最大. 题解: 人生中第一道状压dp~其实还是参考了这篇博客:https://blog.csdn.net/CSDNjiangshan/art

HDU 4336 容斥原理 || 状压DP

状压DP :F(S)=Sum*F(S)+p(x1)*F(S^(1<<x1))+p(x2)*F(S^(1<<x2))...+1; F(S)表示取状态为S的牌的期望次数,Sum表示什么都不取得概率,p(x1)表示的是取x1的概率,最后要加一因为有又多拿了一次.整理一下就可以了. 1 #include <cstdio> 2 const int Maxn=23; 3 double F[1<<Maxn],p[Maxn]; 4 int n; 5 int main() 6

Travel(HDU 4284状压dp)

题意:给n个城市m条路的网图,pp在城市1有一定的钱,想游览这n个城市(包括1),到达一个城市要一定的花费,可以在城市工作赚钱,但前提有工作证(得到有一定的花费),没工作证不能在该城市工作,但可以走,一个城市只能工作一次,问pp是否能游览n个城市回到城市1. 分析:这个题想到杀怪(Survival(ZOJ 2297状压dp) 那个题,也是钱如果小于0就挂了,最后求剩余的最大钱数,先求出最短路和 Hie with the Pie(POJ 3311状压dp) 送披萨那个题相似. #include <