$ \rightarrow $ 戳我进TYVJ原题

[Nescafé29]四叶草魔杖

题目限制

时间限制 内存限制 评测方式 题目来源
1000ms 131072KiB 标准比较器 Local

 

题目背景

陶醉在彩虹光芒笼罩的美景之中,探险队员们不知不觉已经穿过了七色虹,
到达了目的地,面前出现了一座城堡和小溪田园,城堡前的木牌上写着“Poetic Island”。
 
“这一定就是另外两位护法的所在地了……我们快进去吧!”
 
探险队员们快步进入了城堡,城堡大厅的羊毛沙发上坐着两个人。
 
“你们是Nescafe的护法吧?”
 
“是的哦~ 我们就是圣剑护法rainbow和魔杖护法freda~ 你们来这里做什么呢~”
 
“我们是来拜访圣主和四位护法的……”
 
“可是圣主applepi已经前往超自然之界的学校(Preternatural Kingdom University,简称PKU)修炼魔法了,
要想见到他,必须开启Nescafe之塔与超自然之界的通道。但是圣主规定,开启通道的方法不能告诉任何外人。
我只能提示你们,开启通道的钥匙就与四位护法有关T_T”
 
探险队员环视四周,突然,其中一人的目光停留在了魔杖之上。
“hoho~ 魔杖!传说中开启异时空通道的钥匙不就叫四叶草魔杖吗?
四叶草有力量、信心、希望和幸运四片叶子,护法恰好有神刀、飞箭、圣剑、魔杖四位!aha~我找到答案了!”
 
“好吧,那我们就满足你们的愿望~”
 

题目描述

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

输入格式

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

输出格式

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

提示

对于 $ 50 $ % 的数据,$ 2 \le N \le 8 $ 。
对于 $ 100 $ % 的数据,$ 2 \le N \le 16,0 \le M \le N*(N-1)/2,0 \le p_i,q_i<N,-1000 \le A_i \le 1000,0 \le T_i \le 1000,∑A_i=0 $ 。
 

样例数据

输入样例

 3 350 -20 -300 1 101 2 200 2 100

输出样例

 30

 

题解

  • 每个 $ \sum A_i =0 $ 的子图内传递能量的最小代价是其最小生成树

  • 最终整个图可能分成若干块 $ \sum a_i =0 $ 的子图分别传递

  • 以 $ \sum a_i =0 $ 的子图为物品做二进制集合背包的状态压缩 $ DP $
     

代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define inf 1000000007
struct edge{ int u,v,w; }e[205];
int n,m,a[20],f[1<<20],g[1<<20],fa[20],tot;
bool vis[20];
bool cmp(edge x,edge y){ return x.w<y.w; }
int calc(int x){int res=0;for(int i=1;i<=n;++i) if(x&(1<<i-1)) res+=a[i];return res;
}
int find(int x){if(fa[x]!=x) fa[x]=find(fa[x]);return fa[x];
}
int kruskal(int x){int num=0,res=0,tmp=0;memset(vis,0,sizeof(vis));for(int i=1;i<=n;++i){fa[i]=i;if(x&(1<<(i-1))) vis[i]=1,++num;}for(int fu,fv,i=1;i<=m;++i){if(!vis[e[i].u]||!vis[e[i].v]) continue;fu=find(e[i].u); fv=find(e[i].v);if(fu==fv) continue;fa[fu]=fv;res+=e[i].w;++tmp; if(tot==num-1) break;}if(tmp!=num-1) return inf;return res;
}
int main(){scanf("%d %d",&n,&m);for(int i=1;i<=n;++i) scanf("%d",&a[i]);for(int i=1;i<=m;++i){scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);++e[i].u; ++e[i].v;}sort(e+1,e+1+m,cmp);memset(f,0x3f,sizeof(f));f[0]=0;for(int i=1;i<=(1<<n)-1;++i)if(calc(i)==0){int tmp=kruskal(i);if(tmp!=inf) g[++tot]=i; f[i]=tmp;}for(int i=0;i<=(1<<n)-1;++i)for(int j=1;j<=tot;++j)if((i&g[j])==0) f[i|g[j]]=min(f[i|g[j]],f[i]+f[g[j]]);if(f[(1<<n)-1]==inf) puts("Impossible");else printf("%d",f[(1<<n)-1]);return 0;
}

转载于:https://www.cnblogs.com/PotremZ/p/TYVJ2054.html

TYVJ 2054 [Nescafé29]四叶草魔杖 最小生成树 状态压缩/背包DP相关推荐

  1. tyvj 2054 [Nescafé29]四叶草魔杖

    http://www.elijahqi.win/archives/1395 背景 陶醉在彩虹光芒笼罩的美景之中,探险队员们不知不觉已经穿过了七色虹,到达了目的地,面前出现了一座城堡和小溪田园,城堡前的 ...

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

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

  3. HDU 1693(状态压缩 插头DP)

    我们引用国家队2008年陈丹琦的大作--<基于连通性状态压缩的动态规划问题>,上面对于插头.轮廓线的概念有详细的解释,不再赘述. 我们使用一个三维数组,前两维表示所在的格子,后一维表示轮廓 ...

  4. 洛谷 P-4045 密码(AC自动机+状态压缩+数位DP+乱搞)

    洛谷 P-4045 密码 记AC的第一道黑题! 题意:已知一段密码包含了一些字符串,然后求满足条件的密码有多少个,数量小于42时还得全部输出 思路: 一开始WA了两个点,不知道WA的什么,索性把读入的 ...

  5. 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP

    P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...

  6. ZOJ 3502 Contest 状态压缩 概率 DP

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3502 1 #include <iostream> 2 # ...

  7. poj 2923(状态压缩+背包)

    比较巧妙的一道题目,拿到题目就想用暴力直接搜索,仔细分析了下发现复杂度达到了2^n*n! ,明显不行,于是只好往背包上想. 于是又想二分找次数判断可行的方法,但是发现复杂度10^8还是很悬... 然后 ...

  8. Acwing291. 蒙德里安的梦想:状态压缩dp

    文章目录 题目分析 状态表示 状态转移 时间复杂度 题目链接 题目分析 题意重述:给定n*m的方格,看能分成多少个1 *2的小方块. 题目分析: 摆放方块的时候,先放横着的,再放竖着的.总方案数等于只 ...

  9. 【NOIP2013模拟】四叶草魔杖

    [NOIP2013模拟]四叶草魔杖 Time Limits: 1000 ms Memory Limits: 131072 KB Description 魔杖护法Freda融合了四件武器,于是魔杖顶端缓 ...

最新文章

  1. 常见的java异常_浅谈十个常见的Java异常出现原因
  2. Linux 3D 编程学习总结
  3. 【机器学习应用】还没期末考试,算法却说我的物理一定挂科
  4. python3基础学习(双色球随机生成器)
  5. 轻松创建nodejs服务器(1):一个简单nodejs服务器例子
  6. pythonwhile循环love_python基础之while循环及编码
  7. 《Objective-C开发经典教程》
  8. Conflux获上海市政府超过500万美元的研究资助
  9. 定位叠放次序z-index(HTML、CSS)
  10. java 重定向关键字_springboot实现转发和重定向
  11. dns、网关、IP地址,主要是配置resolv.conf\network\ifcfg-eth0
  12. 仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表't_ArticleFiles'中的标识列指定显式值。...
  13. 史上最全Java项目实战课程(含项目实战+源码)
  14. 遥感图像处理学习一、概念及组成
  15. 常见(MySQL)面试题(含答案)
  16. 工业镜头与普通镜头有什么区别?
  17. Blender插件开发:bpy.utils模块
  18. 《计算机网络自顶向下》 Miscellaneous Lab1 Implementing a Reliable Transport Protocol(实现可靠的传输协议(上))
  19. 编辑器工具--通用编辑器工具(持续完善中)
  20. php 精品课程,基于PHP的精品课程教学网站

热门文章

  1. git config 设置,获取,删除
  2. 各种SSD SMART 信息 转
  3. 软件测试及专业,常用软件及专业软件测试
  4. 我们饭碗保住了!谷歌胜,甲骨文败
  5. 计算机组成原理实验报告alu,合肥工业大学计算机组成原理实验报告.doc
  6. 瑞萨IDE:CS+ for CC新建工程配置方法
  7. class mate
  8. PCIe 是什么 ? -- 基本知识
  9. guacamole集成到自己的项目中
  10. 扩充antd的Icon图标库