zoukankan      html  css  js  c++  java
  • 软件补丁问题

    一道冒充网络流的最短路题。
    根据题意,用位运算表示能否转移与转以后的状态。
    (!((u) & (cantinc)[i])) && (!((incw)[i] & (u) ^ (incw)[i]))
    (u)表示旧状态,(cantinc)(can't include),(inc)(include wrong)
    如果旧状态不包含can't include 的,而且包括全部需要include的,那么就可以转移。
    (now)=((u)^ ((u)&(fixx)[i]))|(neww)[i]
    (now)表示新状态,(fixx)表示修复的,(neww)表示新弄出来的漏洞,转移即可。

    但有一个坑点,空间根本开不下Orz
    但是考虑到数据小,可以边spfa,直接暴力枚举。也算开了个新思路。
    Tip:不要在main函数不打spfa,开始怀疑spfa函数写错Orz

    #include <map>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int n,m,t[125];
    char w[125][25],r[125][25];
    int fixx[125],neww[125],incw[125],cantinc[125],dis[1<<20];
    bool inq[1<<20];
    void spfa() {
    	queue<int>q;
    	memset(dis,0x3f,sizeof dis);
    	dis[(1<<n)-1]=0;
    	q.push((1<<n)-1);
    	inq[(1<<n)-1]=1;
    	while(!q.empty()) {
    		int u=q.front();
    		q.pop(),inq[u]=0;
    		for(int i=1; i<=m; i++) {
    			int now=(u^(u&fixx[i]))|neww[i];
    			if((!(u&cantinc[i]))&&(!(incw[i]&u^incw[i]))) {
    				if(dis[u]+t[i]<dis[now]) {
    					dis[now]=dis[u]+t[i];
    					if(!inq[now]) {
    						q.push(now);
    						inq[now]=1;
    					}
    				}
    			}
    		}
    	}
    }
    int main() {
    	scanf("%d%d",&n,&m);
    	for(int i=1; i<=m; i++) scanf("%d%s%s",&t[i],w[i],r[i]);
    	for(int i=1; i<=m; i++) {
    		for(int j=0; j<n; j++) {
    			if(w[i][j]=='-') cantinc[i]|=(1<<j);
    			else if(w[i][j]=='+') incw[i]|=(1<<j);
    		}
    		for(int j=0; j<n; j++) {
    			if(r[i][j]=='-') fixx[i]|=(1<<j);
    			else if(r[i][j]=='+') neww[i]|=(1<<j);
    		}
    	}
    	spfa();
    	printf("%d",dis[0]==0x3f3f3f3f?0:dis[0]);
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    MySql常用命令
    PHP截断函数mb_substr()
    explode() 字符串转换数组
    php取得当前时间函数
    Apache与Nginx的比较
    thinkphp5.0环境变量配置
    thinkphp5.0配置作用域
    thinkphp5.0动态配置
    Mac 下查看 Android Studio 的 SHA1的方法
    Mac 下 gradle 路径
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9280168.html
Copyright © 2011-2022 走看看