传送门

Background

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

“这一定就是另外两位护法的所在地了……我们快进去吧!”

探险队员们快步进入了城堡,城堡大厅的羊毛沙发上坐着两个人。

“你们是Nescafe的护法吧?”

“是的哦~ 我们就是圣剑护法rainbow和魔杖护法freda~ 你们来这里做什么呢~”

“我们是来拜访圣主和四位护法的……”

“可是圣主applepi已经前往超自然之界的学校(Preternatural Kingdom University,简称PKU)修炼魔法了,要想见到他,必须开启Nescafe之塔与超自然之界的通道。但是圣主规定,开启通道的方法不能告诉任何外人。我只能提示你们,开启通道的钥匙就与四位护法有关T_T”

探险队员环视四周,突然,其中一人的目光停留在了魔杖之上。“hoho~ 魔杖!传说中开启异时空通道的钥匙不就叫四叶草魔杖吗?四叶草有力量、信心、希望和幸运四片叶子,护法恰好有神刀、飞箭、圣剑、魔杖四位!aha~我找到答案了!”

“好吧,那我们就满足你们的愿望~”

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

Solution

先用状压dp枚举选出所有sum=0的子图

然后对每一个这样的子图进行kruskal求值最后dp统计即可

Code

//By Menteur_Hxy
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define LL long long
#define M(a,b) memset(a,(b),sizeof(a))
#define F(i,a,b) for(register LL i=(a);i<=(b);i++)
#define E(i,u) for(register LL i=head[u];i;i=e[i].nxt)
using namespace std; LL rd() {
LL x=0,f=1; char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
} const int INF=0x3f3f3f3f;
const int N=17,M=N*N;
int n,m,cnt;
LL da[N],sum[1<<N],dp[1<<N],val[1<<N];
struct edges{int fr,to,w;}e[M]; int fa[N];
int getf(int x) {return fa[x]==x?x:fa[x]=getf(fa[x]);} LL kru(int x) {
int tot=0,ret=0,sum=0;
F(i,0,n-1) if((x>>i)&1) tot++,fa[i]=i;
F(i,1,m) if(((x>>e[i].fr)&1) && ((x>>e[i].to)&1)) {
int fx=getf(e[i].fr),fy=getf(e[i].to);
if(fx!=fy) {
fa[fx]=fy;
ret++;
sum+=e[i].w;
}
}
if(ret+1<tot) return INF;
return sum;
} bool cmp(edges a,edges b) {return a.w<b.w;} int main() {
n=rd(),m=rd();
F(i,0,n-1) da[i]=rd();
F(i,1,m) e[i].fr=rd(),e[i].to=rd(),e[i].w=rd();
sort(e+1,e+1+m,cmp);
LL MAX=(1<<n)-1;
F(i,0,MAX) F(j,0,n-1) if((i>>j)&1) sum[i]+=da[j];
F(i,0,MAX)
if(!sum[i]) val[i]=kru(i);
else val[i]=INF;
F(i,0,MAX) dp[i]=INF;dp[0]=0;
F(i,0,MAX) if(!sum[i]) //这里必须加判断否则会T qwq
F(j,1,MAX) if(!sum[j])
dp[i|j]=min(dp[i|j],dp[i]+val[j]);
if(dp[MAX]==INF) return printf("Impossible"),0;
else printf("%lld",dp[MAX]);
return 0;
}

[tyvj2054] 四叶草魔杖 (最小生成树 状压dp)的更多相关文章

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

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

  2. BZOJ_3058_四叶草魔杖_kruscal+状压DP

    BZOJ_3058_四叶草魔杖_kruscal+状压DP Description 魔杖护法Freda融合了四件武器,于是魔杖顶端缓缓地生出了一棵四叶草,四片叶子幻发着淡淡的七色光.圣剑护法rainbo ...

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

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

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

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

  5. [WC2008]游览计划(状压dp)

    题面太鬼畜不粘了. 题意就是给一张n*m的网格图,每个点有点权,有k个关键点,让你把这k个关键点连成一个联通快的最小代价. 题解 这题nmk都非常小,解法肯定是状压,比较一般的解法插头dp,但不太好写 ...

  6. bzoj1402 Ticket to Ride 斯坦纳树 + 状压dp

    给定\(n\)个点,\(m\)条边的带权无向图 选出一些边,使得\(4\)对点之间可达,询问权值最小为多少 \(n \leqslant 30, m \leqslant 1000\) 首先看数据范围,\ ...

  7. luogu4294 [WC2008]游览计划(状压DP/斯坦纳树)

    link 题目大意:给定一个网格图,有些点是关键点,选择格点有代价,求把所有关键点联通的最小代价 斯坦纳树模板题 斯坦纳树问题:给定一个图结构,有一些点是关键点,求把这些关键点联通的最小代价e 斯坦纳 ...

  8. 【ZJOI2017 Round1练习&BZOJ4774】D3T2 road(斯坦纳树,状压DP)

    题意: 对于边带权的无向图 G = (V, E),请选择一些边, 使得1<=i<=d,i号节点和 n − i + 1 号节点可以通过选中的边连通, 最小化选中的所有边的权值和. d< ...

  9. 洛谷 P3343 - [ZJOI2015]地震后的幻想乡(朴素状压 DP/状压 DP+微积分)

    题面传送门 鸽子 tzc 竟然来补题解了,奇迹奇迹( 神仙题 %%%%%%%%%%%% 解法 1: 首先一件很明显的事情是这个最小值可以通过类似 Kruskal 求最小生成树的方法求得.我们将所有边按 ...

随机推荐

  1. MySQL必知必会面试题 基础

    1.登录数据库 (1).单实例 mysql -uroot -poldboy (2).多实例 mysql -uroot -poldboy -S /data/3306/mysql.sock 2.查看数据库 ...

  2. Eclipse快捷操作

    Eclipse快捷操作 快捷操作,包含了一些鼠标的操作: 学习了:http://www.cnblogs.com/iamfy/archive/2012/07/11/2586869.html 自己体会了一 ...

  3. UnrealEngine4之UObject(一)

    Runtime最关键的实现是UObject,它是全部引擎层面.游戏层面对象的基类. UObject实现了动态创建.持久化.脚本化.内存管理.生存期控制. ----------------------- ...

  4. [React] Forward a DOM reference to another Component using forwardRef in React 16.3

    The function forwardRef allows us to extract a ref and pass it to its descendants. This is a powerfu ...

  5. 怎样又一次编译linux内核

    linux作为自由软件.在广大爱好者的支持下,内核版本号不断更新. 新的内核修订了就得内核的bug,并添加了很多新的特性.假设用户须要使用这些新的特性或者依据自己的系统量身定做一个更高效或更稳定的内核 ...

  6. Python查询数据库,中文的结果显示不出来

    表里面的数据: 问题:查询数据库,返回结果不是中文可以,是中文的话就报错UnicodeEncodeError: 'gbk' codec can't encode character '\xd4' in ...

  7. java泛型具体解释

    为什么引入泛型 bug是编程的一部分,我们仅仅能尽自己最大的能力降低出现bug的几率,可是谁也不能保证自己写出的程序不出现不论什么问题. 错误可分为两种:编译时错误与执行时错误.编译时错误在编译时能够 ...

  8. 利用 Gearman 实现系统错误报警功能

    Gearman 是什么? Gearman是一个用来把工作委派给其他机器.分布式的调用更适合做某项工作的机器.并发的做某项工作在多个调用间做负载均衡.或用来在调用其它语言的函数的系统. Gearman ...

  9. 【HDU 1847】 Good Luck in CET-4 Everybody!

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1847 [算法] 我们知道,每一种状态,要么必胜,要么必败 记忆化搜索即可 [代码] #includ ...

  10. 转四种常见的post请求

    HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 POST 一般用来向服务端提交数据,本文 ...