zoukankan      html  css  js  c++  java
  • [UVA 658] It's not a Bug, it's a Feature! (隐形图,最短路)

    题意:

    有n个bug,m种补补丁的方式,但是补补丁可能是有条件的,比如某个位置必须有bug,或某个位置必须没有bug,且补补丁也有可能在其他地方多生成bug。

    '-'表示某位置有补丁,'+'表示某位置无补丁,'0'是占位符。

    输入多组数据,每组数据输入:

    m n

    t a1 a2 ... an b1 b2 ... bn

    ...

    t a1 a2 ... an b1 b2 ... bn

    a表示补补丁需要的条件,b表示补补丁的操作。

    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.

    思路:

    既然n <= 20,那么很容易想到通过状态压缩表示补丁当前的状态。那么我们需要找出从2n到0的最短路径。于是想到跑一遍最短路。这道题其实是不用建边的,我们只需要每到一个状态跑m种选择,如果符合条件就将终点(处理后的状态)入栈就好了。

    附上AC代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define INF 1061109567
    #define MAX (1 << 20) + 3
    using namespace std;
    // 大致思路:用二进制记录bug位置,每种情况为一个点,目标是从2^n走到0
    // 建图不要先预处理,搜到每个点时再建边每个点判断可以到达的点
    // 最后跑一遍最短路。
    bool book[MAX] = {0};
    int n,m,cost[150],dis[MAX];
    int ch1[110][25],ch2[110][25],top1[110],top2[110];
    
    struct node{
    	int order,ti;
    	bool operator < (const node & other)const{
    		return ti > other.ti;
    	}
    };
    
    priority_queue<node> q;
    node newnode(int x,int y){
    	node p;
    	p.order = x;
    	p.ti = y;
    	return p;
    }
    
    
    int build(int i,int j){// i 状态 j 方案 
    		bool fl = 1;
    		for(int k=0; k<= top1[j]; k++){
    			int r = (i >> (n - k - 1)) & 1;
    			if(ch1[j][k] == '+' && r == 1)continue;
    			if(ch1[j][k] == '-' && r == 0)continue;
    			if(ch1[j][k] == '0')continue;
    			fl = 0;
    			break;
    		}
    		int to = i;
    		if(!fl) return -1;
    		for(int k=0; k<= top2[j]; k++){
    			if(ch2[j][k] == '+')
    				to |= 1 << (n - k - 1);
    			if(ch2[j][k] == '-')//应把第n位修改为零 
    				to &= (1 << n) - 1 - (1 << (n - k - 1));
    		}
    		if(i != to) return to;
    }
    
    void dijkstra(int o){
    	node p;
    	dis[o] = 0;
    	q.push(newnode(o,0));
    	while(!q.empty()){
    		p = q.top();
    		q.pop();
    		if(book[p.order])continue;
    		book[p.order] = 1;
    		for(int j=1;j<=m;j++){
    			int to = build(p.order,j);
    			if(to != -1){
    				if(p.ti + cost[j] < dis[to])
    					dis[to] = p.ti + cost[j],
    					q.push(newnode(to,dis[to]));
    			}
    		}		
    	} 
    }
    
    int main(){
    	int T = 0;
    	while(scanf("%d%d",&n,&m) == 2){
    	if(n == 0 && m == 0)break;
    	memset(dis,0x3f,sizeof(dis));
    	memset(book,0,sizeof(book));
    	char c;
    	
    	for(int i=1; i<=m; i++){
    		top1[i] = -1;
    		scanf("%d ",&cost[i]);
    		c = getchar();
    		while(c == '0' || c == '+' || c == '-') 
    		ch1[i][++top1[i]] = c,c = getchar();
    		
    		top2[i] = -1;
    		c = getchar();
    		while(c == '0' || c == '+' || c == '-') 
    		ch2[i][++top2[i]] = c,c = getchar();
    	}
    	
    	dijkstra((1<<n) - 1);
    	if(dis[0] != INF)
    		printf("Product %d
    Fastest sequence takes %d seconds.
    
    ",++T,dis[0]);
    	else printf("Product %d
    Bugs cannot be fixed.
    
    ",++T);
    }
    	return 0;
    } 
    
  • 相关阅读:
    安装Django、Nginx和uWSGI
    创建Orcale数据库链接访问外部数据库
    ER图,以及转化成关系模式
    eclipse中的Java项目导出成为一个可以直接双击运行的jar文件
    电脑添加新的字体
    JDBC 的编程步骤
    转转基础服务性能压测实战
    公司起诉CTO拖延研发进度,索赔90万
    详解MQ消息队列及四大主流MQ的优缺点
    晒一波程序员的杯子,逼格超级高
  • 原文地址:https://www.cnblogs.com/Cindy-Chan/p/11391609.html
Copyright © 2011-2022 走看看