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
  • 相关阅读:
    python 和 R 语言中的等差数列
    python 用 matplotlib 绘制误差条图
    Python 模拟伯努利试验和二项分布
    R 基于朴素贝叶斯模型实现手机垃圾短信过滤
    PCA 在手写数字数据集上的应用
    R 实现朴素贝叶斯分类器模型
    R语言 绘制正(余)弦图
    R 绘制反正(余)弦图像
    R 绘制正(余)切图像
    R 语言 do.call() 函数
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9280168.html
Copyright © 2011-2022 走看看