BZOJ_3058_四叶草魔杖_kruscal+状压DP

Description

魔杖护法Freda融合了四件武器,于是魔杖顶端缓缓地生出了一棵四叶草,四片叶子幻发着淡淡的七色光。圣剑护法rainbow取出了一个圆盘,圆盘上镶嵌着N颗宝石,编号为0~N-1。第i颗宝石的能量是Ai。如果Ai>0,表示这颗宝石能量过高,需要把Ai的能量传给其它宝石;如果Ai<0,表示这颗宝石的能量过低,需要从其它宝石处获取-Ai的能量。保证∑Ai =0。只有当所有宝石的能量均相同时,把四叶草魔杖插入圆盘中央,才能开启超自然之界的通道。
不过,只有M对宝石之间可以互相传递能量,其中第i对宝石之间无论传递多少能量,都要花费Ti的代价。探险队员们想知道,最少需要花费多少代价才能使所有宝石的能量都相同?

Input

第一行两个整数N、M。
第二行N个整数Ai。
接下来M行每行三个整数pi,qi,Ti,表示在编号为pi和qi的宝石之间传递能量需要花费Ti的代价。数据保证每对pi、qi最多出现一次。

Output

输出一个整数表示答案。无解输出Impossible。

Sample Input

3 3
50 -20 -30
0 1 10
1 2 20
0 2 100

Sample Output

30

HINT

对于 100% 的数据,2<=N<=16,0<=M<=N*(N-1)/2,0<=pi,qi<N,-1000<=Ai<=1000,0<=Ti<=1000,∑Ai=0。


可以转化成这样一个问题:将原图划分成若干个连通块,使得每个连通块内权值和为0,求最小代价。

由于n特别小可以状压,f[i]表示状态为i时最小的联通代价。

对于每个和为0的集合,用kruscal求使这个集合连通的最小代价,然后DP即可。

代码:

#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
int cal[1<<16],n,m,a[20],f[1<<16],g[1<<16],fa[20];
struct E {
int x,y,z;
bool operator < (const E &u) const {
return z<u.z;
}
}e[350];
int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
void dfs(int dep,int sta,int sum) {
if(dep==n) {
cal[sta]=sum; return ;
}
dfs(dep+1,sta|(1<<dep),sum+a[dep+1]);
dfs(dep+1,sta,sum);
}
void build(int sta) {
int i,num=0;
for(i=1;i<=n;i++) {
fa[i]=i; if(sta&(1<<(i-1))) num++;
}
int re=0,cnt=0;
for(i=1;i<=m;i++) {
int dx=find(e[i].x),dy=find(e[i].y);
if((sta&(1<<(dx-1)))&&(sta&(1<<(dy-1)))&&dx!=dy) {
fa[dx]=dy; re+=e[i].z; cnt++; if(cnt==num-1) break;
}
}
if(cnt==num-1) f[sta]=re;
}
int main() {
// freopen("shield.in","r",stdin);
// freopen("shield.out","w",stdout);
scanf("%d%d",&n,&m);
int i,j;
for(i=1;i<=n;i++) scanf("%d",&a[i]);
dfs(0,0,0);
for(i=1;i<=m;i++) {
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z); e[i].x++; e[i].y++;
}
sort(e+1,e+m+1);
int mask=(1<<n)-1;
memset(f,0x3f,sizeof(f));
f[0]=0;
for(i=1;i<=mask;i++) {
if(cal[i]==0) {
build(i);
}
}
for(i=0;i<=mask;i++) {
for(j=i&(i-1);j;j=i&(j-1)) {
if(f[j]<=1000000&&f[i-j]<=1000000) f[i]=min(f[i],f[j]+f[i-j]);
}
}
if(f[mask]<=10000000) printf("%d\n",f[mask]);
else puts("Impossible");
}
/*
3 3
50 -20 -30
0 1 10
1 2 20
0 2 100
*/

BZOJ_3058_四叶草魔杖_kruscal+状压DP的更多相关文章

  1. [tyvj2054] 四叶草魔杖 (最小生成树 状压dp)

    传送门 Background 陶醉在彩虹光芒笼罩的美景之中,探险队员们不知不觉已经穿过了七色虹,到达了目的地,面前出现了一座城堡和小溪田园,城堡前的木牌上写着"Poetic Island&q ...

  2. BZOJ.3058.四叶草魔杖(Kruskal 状压DP)

    题目链接 \(2^{16}=65536\),可以想到状压DP.但是又有\(\sum A_i\neq 0\)的问题.. 但是\(2^n\)这么小,完全可以枚举所有子集找到\(\sum A_i=0\)的, ...

  3. tyvj 2054 [Nescafé29]四叶草魔杖——最小生成树+状压dp

    题目:http://www.joyoi.cn/problem/tyvj-2054 枚举点集,如果其和为0,则作为一个独立的块求一下最小生成树.因为它可以不和别的块连边. 然后状压dp即可. 别忘了判断 ...

  4. tyvj2054 四叶草魔杖——连通块 & 状压DP

    题目:http://www.joyoi.cn/problem/tyvj-2054 把点分成几个连通块,和为0的几个点放在一块,在块内跑最小生成树作为这个块的代价: 然后状压DP,组成全集的最小代价就是 ...

  5. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  6. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  7. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  8. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  9. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

随机推荐

  1. HDU-1232/NYOJ-608畅通工程,并查集模板题,,水过~~~

    畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) http://acm. ...

  2. CSU1030素数槽

    Description 处于相邻的两个素数p和p + n之间的n - 1个连续的合数所组成的序列我们将其称为长度为n的素数槽.例如,‹24, 25, 26, 27, 28›是处于素数23和素数29之间 ...

  3. 【区间筛】2017多校训练四 HDU6069 Counting Divisors

    http://acm.hdu.edu.cn/showproblem.php?pid=6069 [题意] 给定l,r,k,求 d(n)是n的因子个数 [思路] [Accepted] #include&l ...

  4. ES6__函数的扩展

    /** * 函数的扩展 * 1 为函数参数指定默认值 * 2 函数的 rest 参数 * 3 箭头函数 */ // ------------------------------------------ ...

  5. msp430项目编程24

    msp430中项目---MMC接口 1.串行通信工作原理 2.串行通信协议 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习

  6. markdown八条基础语法

    1.空行 答:使用全角打出空格,之后再换行就可以打出空行了 2.标题 答:#表示标题,#表示一级标题,字号最大,一共有六级标题 3.列表 答:- 无序列表,1. 有序列表,注意和文本之间有空格 4.链 ...

  7. T1992 聚会 codevs

    http://codevs.cn/problem/1992/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 小S 想要从某地 ...

  8. MySQL查询在一个表而不在另一个表中的数据

    1.使用not in,容易理解,效率低 select distinct A.ID from A where A.ID not in (select ID from B) 2.使用left join.. ...

  9. 基于unicorn-engine的虚拟机的实现(WxSpectre)

    反病毒虚拟机是一个很有优势的工具,可以说反病毒软件是否存在模拟器是衡量反病毒软件能力的一个指标.反病毒虚拟机不光是内嵌在反病毒软件内部,来动态执行样本.这种虚拟机一般也可以单独用来动态执行批量样本,检 ...

  10. JAVA_the user operation is waiting怎么办

    彻底解决 MyEclipse出现the user operation is waiting的问题   2011-05-31 10:32:30|  分类: 软件编程 |  标签:java  myecli ...