软件补丁问题
Description
T
公司发现其研制的一个软件中有
每一个补丁程序都有其特定的适用环境,某个补丁只有在软件中包含某些错误而同时又不包含另一些错误时才可以使用。
一个补丁在排除某些错误的同时,往往会加入另一些错误。
换句话说,对于每一个补丁
补丁
另外,每个补丁都耗费一定的时间。
试设计一个算法,利用
T
公司提供的
对于给定的
n
个错误和
Input
第
1
行有
接下来
m
行给出了
每行包括一个正整数,表示运行补丁程序
i
所需时间,以及
第
第
2
个字符串中,如果第
Output
将总耗时数输出。如果问题无解,则输出 0 。
Sample Input
3 3
1 000 00-
1 00- 0-+
2 0– -++
Sample Output
8
Solution
一看到这道题目我就惊呆了——这跟网络流能扯到一块儿??
因为
但是很快就愉快地发现,本题就是一个水水的最短路……
我之前的想法其实也没有错,状态压缩,求最短路即可。
Code
代码很丑,不要介意……
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <queue>
- #define INF 0x3f3f3f3f
- using namespace std;
- int cnt;
- queue<int>q;
- bool in_stack[1100010];
- int dis[1100010];
- int head[1100010];
- int nxt[1100010];
- int data[1100010];
- int wei[1100010];
- int n,m;
- int tt[5000];
- char s1[5000],s2[5000];
- bool b1[200][200];
- bool b2[200][200];
- bool f1[200][200];
- bool f2[200][200];
- bool vis[1100010][101];
- int zz[100];
- void add(int x,int y,int z){
- nxt[cnt]=head[x];data[cnt]=y;wei[cnt]=z;head[x]=cnt++;
- }
- int Can(int tot,int now){
- int tmp=0;
- zz[0]=0;
- for(int i=1;i<=n;i++)zz[i]=0;
- while(now){
- zz[++zz[0]]=now%2;
- now/=2;
- }
- for(int i=n;i>=1;i–){
- if((zz[i]==0&&b1[tot][n-i+1]))return -1;
- if(zz[i]==1&&b2[tot][n-i+1])return -1;
- }
- for(int i=n;i>=1;i–){
- if(f1[tot][n-i+1])zz[i]=0;
- if(f2[tot][n-i+1])zz[i]=1;
- tmp+=(1<<(i-1))*zz[i];
- }
- return tmp;
- }
- void dfs(int now){
- if(now==0)return;
- for(int i=1;i<=m;i++){
- int tmp=Can(i,now);
- if(tmp==-1)continue;
- if(vis[tmp][i])add(now,tmp,tt[i]);
- else{
- add(now,tmp,tt[i]);
- vis[tmp][i]=true;
- dfs(tmp);
- }
- }
- }
- void spfa(){
- memset(dis,0x3f,sizeof dis);
- q.push((1<<n)-1);
- dis[(1<<n)-1]=0;
- in_stack[(1<<n)-1]=true;
- while(!q.empty()){
- int now=q.front();
- q.pop();
- in_stack[now]=false;
- for(int i=head[now];i!=-1;i=nxt[i]){
- if(dis[data[i]]>dis[now]+wei[i]){
- dis[data[i]]=dis[now]+wei[i];
- if(!in_stack[data[i]]){
- q.push(data[i]);
- in_stack[data[i]]=true;
- }
- }
- }
- }
- if(dis[0]==INF)printf(“0\n”);
- else printf(“%d\n”,dis[0]);
- }
- int main(){
- memset(head,-1,sizeof head);
- scanf(”%d%d”,&n,&m);
- for(int i=1;i<=m;i++){
- scanf(”%d%s%s”,&tt[i],s1,s2);
- for(int j=0;j<n;j++){
- if(s1[j]==‘0’)continue;
- if(s1[j]==‘+’)b1[i][j+1]=true;
- if(s1[j]==‘-‘)b2[i][j+1]=true;
- }
- for(int j=0;j<n;j++){
- if(s2[j]==‘0’)continue;
- if(s2[j]==‘-‘)f1[i][j+1]=true;
- if(s2[j]==‘+’)f2[i][j+1]=true;
- }
- }
- dfs((1<<n)-1);
- spfa();
- return 0;
- }
- 原题中,此处及下一个 ‘+’ 处弄混了,已予以修正。 ↩