Time Limit: 5000MS | Memory Limit: 30000K | |
Total Submissions: 1205 | Accepted: 456 |
Description
Input
Output
Sample Input
3 3 1 000 00- 1 00- 0-+ 2 0-- -++ 4 1 7 0-0+ ---- 0 0
Sample Output
Product 1 Fastest sequence takes 8 seconds. Product 2 Bugs cannot be fixed.
Source
题目大意:有n个bug,现在给m个补丁,每个补丁有作用时间,每个补丁工作有一定的前提条件,当某些bug必须存在,某些bug必须不存在的时候该补丁才能工作,补丁作用完后会修复一些bug也会产生新的bug。求这m个补丁修复好n个bug要的最短时间。
题目分析:bfs+状态压缩+优先队列。设bug存在置为状态1,bug被修复了置为状态0,初态是n个1,终态是n个0,由于n<=20,可以压缩到一个整数里面,那么初始状态就是2^n - 1,终态就是0。把每个补丁工作的条件用2个整数表示,can1表示该补丁工作时必须存在的补丁的位置,can2表示该补丁工作使不能存在补丁的位置,都用1标识出来。补丁作用完后也用2个整数表示修复后的状态,fixed表示补丁工作完后被修复的bug的位置,unfixed表示补丁工作完后新产生bug的位置。这样可以直接用位操作判断补丁是否能工作以及补丁工作完后的状态。不过这样写完后提交很可能会wa,这是因为这m个补丁要修复n个bug可能有多种方式,所需要的时间也就不同,由于补丁给的顺序不同,所以最优解不一定先产生,所以单纯的用单调队列还不够,具体的可以看看后面给的例子。判重的时候可以记录下到达该状态的时候所需要的步数,如果再次到达该状态可能步数更少些,应该再次入队,这点很重要,跪了一下午。。。。
详情请见代码:
#include
#include
#include
#include
#include
using namespace std;
int flag[2000000];
int n,m;
struct node
{
int step,state;
bool operator < (const struct node &b)const
{
return step > b.step;
}
}ss,now;
struct nd
{
int can1,can2;
int fixed,unfixed;
int sec;
}patch[105];
priority_queue q;
int bfs()
{
int i;
ss.state = (1< ss.step)
{
flag[ss.state] = ss.step;
q.push(ss);
}
}
}
}
while(!q.empty())
q.pop();
return ret;
}
int nextint()
{
char c;
int ret = 0;
while(isspace(c = getchar()))
;
ret = c - '0';
while((c = getchar()) >= '0' && c <= '9')
ret = ret * 10 + c - '0';
return ret;
}
int main()
{
int i,j;
int cas = 0;
char c;
while(scanf("%d%d",&n,&m) && (m + n))
{
for(i = 1;i <= m;i ++)
{
patch[i].sec = nextint();
while(isspace(c = getchar()))
;
j = 1;
patch[i].can1 = patch[i].can2 = 0;
while(!isspace(c))
{
if(c == '0')
c = getchar();
else
{
if(c == '+')
patch[i].can1 |= 1<<(n - j);
else
patch[i].can2 |= 1<<(n - j);
c = getchar();
}
j ++;
}
while(isspace(c = getchar()))
;
j = 1;
patch[i].fixed = patch[i].unfixed = 0;
while(!isspace(c))
{
if(c == '0')
c = getchar();
else
{
if(c == '-')
patch[i].fixed |= 1<<(n - j);
else
patch[i].unfixed |= 1<<(n - j);
c = getchar();
}
j ++;
}
}
int ans = bfs();
printf("Product %d\n",++cas);
if(ans == -1)
printf("Bugs cannot be fixed.\n\n");
else
printf("Fastest sequence takes %d seconds.\n\n",ans);
}
return 0;
}
//203MS 8108K //140MS 4980K
/*
3 4
8 000 ---
2 000 00-
2 00- 0--
2 0-- ---
3 3
1 000 00-
1 00- 0-+
2 0-- -++
4 1
7 0-0+ ----
4 1
3 0000 ----
20 20
4 00000000000000000000 0000000000000000000-
16 0000000000000000000- 000000000000000000-+
14 000000000000000000-- 00000000000000000-++
12 00000000000000000--- 0000000000000000-+++
13 0000000000000000---- 000000000000000-++++
19 000000000000000----- 00000000000000-+++++
4 00000000000000------ 0000000000000-++++++
6 0000000000000------- 000000000000-+++++++
12 000000000000-------- 00000000000-++++++++
1 00000000000--------- 0000000000-+++++++++
13 0000000000---------- 000000000-++++++++++
3 000000000----------- 00000000-+++++++++++
12 00000000------------ 0000000-++++++++++++
19 0000000------------- 000000-+++++++++++++
13 000000-------------- 00000-++++++++++++++
18 00000--------------- 0000-+++++++++++++++
1 0000---------------- 000-++++++++++++++++
3 000----------------- 00-+++++++++++++++++
17 00------------------ 0-++++++++++++++++++
18 0------------------- -+++++++++++++++++++
1 1
2 - -
1 1
3 + +
1 1
4 + -
1 1
5 - +
0 0
*/