【t064】最勇敢的机器人
2017-10-06 19:23
246 查看
Time Limit: 1 second
Memory Limit: 128 MB
【问题描述】
【背景】Wind设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了~
【问题描述】
机器人们都想知道谁是最勇敢的,于是它们比赛搬运一些物品。
它们到了一个仓库,里面有n个物品,每个物品都有一个价值Pi和重量Wi,但是有些物品放在一起会爆炸,并且爆炸具有传递性。
(a和b会爆炸、b和c会爆炸则a和c会爆炸)机器人们可不想因此损失自己好不容易从Wind那里敲诈来的装备,于是它们想知道在
能力范围内,它们最多可以拿多少价值的物品。
你能帮助它们吗?
【输入格式】
每组测试数据第1行为n,Wmax,k(0<=n,Wmax,k<=1000)
接下来n行,为每个物品的Pi,Wi(0<=Pi<=1000,1<=Wi<=10,均为整数)
再接下来k行,每行2个数字a,b表示a和b会发生爆炸
【输出格式】
对每组数据输出1行
为最大可能价值
Sample Input
3 10 1 100 1 200 5 10 5 1 2
Sample Output
210
【题解】
a和b会发生爆炸。即a,b中只能选一个。也即分组背包问题。
首先,如果x和y会发生爆炸就把x和y合并在一起(并查集),然后根据合并的情况构造出k组物品。每组中都只能选取一个物品。
然后先for k组背包。表示按照组的顺序进行背包的操作。
然后是for 容量。表示接下来为j容量选取一个物品。
然后是for第k组物品中的具体每一个物品。
因为先for的是容量。所以可以保证。只会选取第k组物品中的一个物品。
最后输出答案即可。
【代码】
#include <cstdio> int fa[1001],n,wmax,k,c[1001],w[1001],f[1001],next[1001],first[1001],what[1001],num = 0; int findfather(int x) //用来寻找根节点,同时路径压缩 { if (fa[x] != x) fa[x] = findfather(fa[x]); return fa[x]; } int main() { //freopen("F:\\rush.txt","r",stdin); scanf("%d%d%d",&n,&wmax,&k); for (int i = 1;i <= n;i++) scanf("%d%d",&c[i],&w[i]); for (int i = 1;i <= n;i++) //并查集数组初始化操作 fa[i] = i; for (int i = 1;i <= k;i++) //输入k个抵触关系 { int x,y; scanf("%d%d",&x,&y); int r1 = findfather(x),r2 = findfather(y); if (r1 != r2) //把这两个物品合并在一起,即同一组物品 fa[r2] = r1; } for (int i = 1;i <= n;i++) //把所有的子节点指向根节点 findfather(i); int bo[1001] = {0}; //用来标记某一个物品是哪一组的物品 k = 0; for (int i =1;i <= n;i++) if (bo[fa[i]] == 0) //这是第一次出现第k组物品的处理方法 { k++; bo[fa[i]] = k; num++; next[num] = first[k]; //这里用了邻接表来记录k组物品的每一个物品 为了省空间 what[num] = i; first[k] = num; } else //不是第一次出现则记录就好 可以缩短代码。。想缩短就缩吧。-> 邻接表那段可以不用写两次 { num++; next[num] = first[bo[fa[i]]]; what[num] = i; first[bo[fa[i]]] = num; } for (int i = 1;i <= k;i++) //进行分组背包的操作 for (int j = wmax;j >= 0;j--) { int temp = first[i]; //这是邻接表读取数据的方法 while (temp != 0) { int l = what[temp]; if (j >= w[l]) //如果没有超过背包容量 则进行更新 { if (f[j] < f[j-w[l]] + c[l]) f[j] = f[j-w[l]] + c[l]; } temp = next[temp]; } } printf("%d",f[wmax]); //最后输出答案。 return 0; }
相关文章推荐
- 最勇敢的机器人
- Vijos P1250 最勇敢的机器人
- Vijos P1250 - 最勇敢的机器人
- vijos 1250 最勇敢的机器人 分组背包+并查集
- 最勇敢的机器人(Vijos-1250)
- vijos 1250 最勇敢的机器人
- vijos1250 最勇敢的机器人
- vijos1250 最勇敢的机器人
- 最勇敢的机器人
- 【Vijos1250】最勇敢的机器人(并查集,分组背包DP)
- Vijos P1250最勇敢的机器人 dp 分组背包
- python实现美空图片抓取机器人
- Java TCP、IO流实现简单机器人聊天系统
- 人工智能:用AIML写一个机器人
- zabbix调用telegram机器人发送报警消息
- 机器人国际顶级会议 (Robotics international conference)
- Python微信机器人
- OE6388U语音合成模块(TTS) 让设备说话(机器人)SYN6658
- Canvas类和Paint的绘制机器人
- 海阔天空 在勇敢以后 --我的求职路