UVa 658 - It's not a Bug, it's a Feature!(Dijkstra + 隐式图搜索)
链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=599
题意:
补丁在修正bug时,有时也会引入新的bug。假定有n(n≤20)个潜在bug和m(m≤100)个补丁,
每个补丁用两个长度为n的字符串表示,其中字符串的每个位置表示一个bug。
第一个串表示打补丁之前的状态(“-”表示该bug必须不存在,“+”表示必须存在,0表示无所谓),
第二个串表示打补丁之后的状态(“-”表示不存在,“+”表示存在,0表示不变)。
每个补丁都有一个执行时间,你的任务是用最少的时间把一个所有bug都存在的软件通过打补丁的方式变得没有bug。
一个补丁可以打多次。
分析:
在任意时刻,每个bug可能存在也可能不存在,所以可以用一个n位二进制串表示当前软件的“状态”。
打完补丁之后,bug状态会发生改变,对应“状态转移”。
把状态看成结点,状态转移看成边,转化成图论中的最短路径问题,然后使用Dijkstra算法求解。
不过这道题和普通的最短路径问题不一样:结点很多,多达2^n个,
而且很多状态根本遇不到(即不管怎么打补丁,也不可能打成那个状态),所以没有必要先把图储存好。
用隐式图搜索即可:当需要得到某个结点u出发的所有边时,直接枚举所有m个补丁,看看是否能打得上。
代码:
import java.io.*;
import java.util.*;
import static java.util.Arrays.*; public class Main {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
final int INF = 0x3f3f3f3f;
final int UPN = 20;
final int UPM = 100;
int n, m, sec[] = new int[UPM], d[] = new int[1<<UPN];
char before[][] = new char[UPM][UPN], after[][] = new char[UPM][UPN];
boolean done[] = new boolean[1<<UPN]; class Node implements Comparable<Node> {
int s, dist; Node(int s, int dist) {
this.s = s;
this.dist = dist;
} @Override
public int compareTo(Node that) {
return dist - that.dist;
}
} int dijkstra() {
fill(d, INF);
fill(done, false);
int ori = (1<<n) - 1;
PriorityQueue<Node> Q = new PriorityQueue<Node>();
d[ori] = 0;
Q.add(new Node(ori, 0));
while(Q.size() > 0) {
Node cur = Q.poll();
if(cur.s == 0) return cur.dist;
if(done[cur.s]) continue;
done[cur.s] = true;
for(int t = 0; t < m; t++) {
boolean patchable = true;
for(int i = 0; i < n; i++) {
if(before[t][i] == '+' && (cur.s&(1<<i)) == 0) { patchable = false; break; }
else if(before[t][i] == '-' && (cur.s&(1<<i)) > 0) { patchable = false; break; }
}
if(!patchable) continue; Node temp = new Node(cur.s, cur.dist + sec[t]);
for(int i = 0; i < n; i++) {
if(after[t][i] == '+') temp.s |= (1<<i);
else if(after[t][i] == '-') temp.s &= ~(1<<i);
}
if(d[temp.s] > temp.dist) {
d[temp.s] = temp.dist;
Q.add(temp);
}
}
}
return -1;
} void MAIN() {
for(int cases = 1; ; cases++) {
n = cin.nextInt();
m = cin.nextInt();
if(n + m == 0) break;
for(int i = 0; i < m; i++) {
sec[i] = cin.nextInt();
before[i] = cin.next().toCharArray();
after[i] = cin.next().toCharArray();
}
int ans = dijkstra();
System.out.printf("Product %d\n", cases);
if(ans < 0) System.out.printf("Bugs cannot be fixed.\n\n");
else System.out.printf("Fastest sequence takes %d seconds.\n\n", ans);
}
} public static void main(String args[]) { new Main().MAIN(); }
}
UVa 658 - It's not a Bug, it's a Feature!(Dijkstra + 隐式图搜索)的更多相关文章
- UVA - 658 It's not a Bug, it's a Feature! (隐式图的最短路,位运算)
隐式的图搜索,存不下边,所以只有枚举转移就行了,因为bug的存在状态可以用二进制表示,转移的时候判断合法可以用位运算优化, 二进制pre[i][0]表示可以出现的bug,那么u&pre[i][ ...
- UVA 658 It's not a Bug, it's a Feature! (最短路,经典)
题意:有n个bug,有m个补丁,每个补丁有一定的要求(比如某个bug必须存在,某个必须不存在,某些无所谓等等),打完出来后bug还可能变多了呢.但是打补丁是需要时间的,每个补丁耗时不同,那么问题来了: ...
- UVA 658 It's not a Bug, it's a Feature!
这个题目巧妙之处在于用二进制的每个位1,0分别表示bug的有无,以及实施补丁对相应bug的要求以及实施后的对bug的影响. 软件bug的状态:1表示相应bug仍然存在,0表示已经修复.这样可以将软件的 ...
- UVa 658 It's not a Bug, it's a Feature! (状态压缩+Dijstra)
题意:首先给出n和m,表示有n个bug和m个补丁.一开始存在n个bug,用1表示一个bug存在0表示不存在,所以一开始就是n个1,我们的目的是要消除所有的bug, 所以目标状态就是n个0.对于每个补丁 ...
- 【UVA】658 - It's not a Bug, it's a Feature!(隐式图 + 位运算)
这题直接隐式图 + 位运算暴力搜出来的,2.5s险过,不是正法,做完这题做的最大收获就是学会了一些位运算的处理方式. 1.将s中二进制第k位变成0的处理方式: s = s & (~(1 < ...
- 【uva 658】It's not a Bug, it's a Feature!(图论--Dijkstra或spfa算法+二进制表示+类“隐式图搜索”)
题意:有N个潜在的bug和m个补丁,每个补丁用长为N的字符串表示.首先输入bug数目以及补丁数目.然后就是对M个补丁的描述,共有M行.每行首先是一个整数,表明打该补丁所需要的时间.然后是两个字符串,第 ...
- 状态转移的最短路 隐式图搜索 UVA 658
紫书365 题目大意:给你n个全都是bug的东西,然后每次可以修复,给你修复前后的状态,问最后如果能把bug全都修复,最少需要多少时间. 思路:从最初状态开始,然后枚举bug即可. 表示priorit ...
- 紫书 例题 11-6 UVa 658 (状态压缩+隐式图搜索+最短路)
这道题用到了很多知识点, 是一道好题目. 第一用了状态压缩, 因为这里最多只有20位, 所以可以用二进制来储存状态 (要对数据范围敏感), 然后 涉及到了一些位运算. 第二这里是隐式 ...
- uva 10274 Fans and Gems(隐式图搜索+模拟)
Fans and Gems Input: Standard Input Output: Standard Output Tomy's fond of a game called 'Fans and G ...
随机推荐
- TSM简介
转自:https://www.cnblogs.com/Study-Blog/p/8644376.html Tivoli TSM产品功能详述Tivoli TSM(Tivoli Storage Manag ...
- [android] 切换界面的通用处理
实现不改变activity,只切换View 抽取View界面的基类 利用面向对象多态的思路,实现通用 TitleManager.java 管理标题 package com.tsh.lottery.vi ...
- [javaEE] javaweb的mvc设计思想
Servlet:在Servlet中拼接html内容 JSP:在html中拼接java JSP+JavaBean:利用javaBean将大量的代码提取走 Servlet+JSP+JavaBean:Ser ...
- csharp: using using System.Web.Script.Serialization read json
using System; using System.Data; using System.Configuration; using System.Collections; using System. ...
- 修改vue的配置项支持生产环境下二级目录访问的方法
本文主要记录如何配置vue的打包文件配置项,使打包后的文件可以支持二级目录的访问. 1.常规打包 在实际的项目中,我们通常都使用 npm run build 直接打包文件后丢到服务器上访问 打包后的文 ...
- 教你小三角,适用移动端等,解决移动端a标签的默认样式
1.小三角,通过给一个div设置足够大的边框,让它的上边框,右边框,左边框,的背景颜色设置成透明的,来实现,如下: <!DOCTYPE html> <html> <hea ...
- Java Struts2 (二)
二.封装请求正文到对象中(非常重要) 1.静态参数封装 在struts.xml配置文件中,给动作类注入值.调用的是setter方法. 原因:是由一个staticParams的拦截器完成注入的. 2.动 ...
- <Android 基础(二十)> CoordinatorLayout Behavior
介绍 Interaction behavior plugin for child views of {@link CoordinatorLayout}. A Behavior implements o ...
- Ubuntu 18.04 的网络配置
netplan简介 目前,ubuntu18.04上使用了netplan 作为网络配置工具:在终端上配置网络参数跟之前的版本有比较大的差别 Netplan工作流程如下图所示:通过读取 /etc/net ...
- UTF-8文件编码格式中有无签名问题汇总(BOM)
UTF-8签名(UTF-8 signature)也叫做BOM(Byte order Mark),是UTF编码方案里用于标识编码的标准标记.如果多个文件设置了签名,在二进制流中就会包含多个UTF-8签名 ...