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 6113 度度熊的01世界

    http://acm.hdu.edu.cn/showproblem.php?pid=6113 [题意] 度度熊是一个喜欢计算机的孩子,在计算机的世界中,所有事物实际上都只由0和1组成. 现在给你一个n ...

  2. private、protected和public的区别

    private 是完全私有的,只有当前类中的成员能访问到. protected 是受保护的,只有当前类的成员与继承该类的类才能访问. 这两个是访问类中成员权限的限制符.在类外如果想使用类中的成员,只能 ...

  3. CF613A:Peter and Snow Blower

    用一个圆心在(x,y)的圆环覆盖一个n边形,顺或逆时针给出n边形所有顶点,求圆环最小面积. 卡了好久,各种傻逼错误.. 题目就是让我们固定一大一小两个边界圆,我们来看看这两个圆满足什么条件. 首先外面 ...

  4. isNaN+parseFloat进行统计以及对NaN的处理【JS验证数字】

    今天遇到这么一个需求: 对数据进行统计,可是在统计的时候parseFloat的时候出来一个NaN.后来用isNaN判断,如果是NaN,就给其设置一个初值. 先看对两个方法的解释 parseFloat: ...

  5. bitset初始化问题

    在C++primer上面说,bitset可以用unsigned long来进行初始化,但是上面的例子只是采用了常数如0xffff,而在实际中,当在vs2010中,我采用unsigned long类型的 ...

  6. POJ 2240 【这题貌似可以直接FLOYD 屌丝用SPFA通过枚举找正权值环 顺便学了下map】

    题意: 给了n种硬币的名称,给了m种硬币间的转换关系. 从任意兑换地点开始兑换,看是否能够通过兑换的方式增加金钱. 思路: 用SPFA不断对各个点进行松弛操作,寻找正权值的环.如果找到则输出Yes. ...

  7. IOCP实现的任务队列

    unit IOCPQueue; interface uses windows, classes; type TOnQueueProc = procedure(sender: tobject; Para ...

  8. 使用nginx代理weblogic负载方案

    之前一直用apache来做weblogic的前端,由于nginx对静态内容的出色性能,不得不转投nginx.这里就不 再写weblogic的安装了. 安装nginx nginx需要pcre做支持,一般 ...

  9. 解决Coldfusion连接MySQL数据库的问题

    在连接MySQL时,出现了如下错误: Connections to MySQL Community Server are not supported. Please contact MySQL to ...

  10. sgu208:Toral Tickets(P&#243;lya定理)

    题意简述:给你N和M,对于一个N∗M的单面方格纸你能够对它的每 个个格子黑白染色.然后把方格纸的长边卷起来,卷成一个圆柱体,然后再把 两个短边形成的圆也接起来.形成一个游泳圈的形状(我们染的色仅仅在游 ...