標籤:利用 不能 ace 產生 i++ 並且 stdin 輸出 答案
【問題描述】對於一個軟體公司來說,在發行一個新軟體之後,可以說已經完成了工作。但是實際上,許多軟體公司在發行一個新產品之後,還經常發送補丁程式,修改原產品中的錯誤(當然,有些補丁是要收費的)。如某微硬公司就是這樣的一個軟體公司。今年夏天,在發行了一個新的文書處理軟體之後,到現在他們已經編寫了許多補丁程式。僅僅在這個周末,他們就用新編寫的補丁程式解決了軟體中的一個大問題。而在每一個補丁程式修改軟體中的某些錯誤時,有可能引起軟體中原來存在的某些錯誤重新發作。發生這種情況是因為當修改一個錯誤時,補丁程式利用了程式中約定的特別行為,從而導致錯誤的重新產生。微硬公司在他們的軟體中一共發現了n個錯誤B={bl,b2,…,bn),現在他們一共發送了m 個補丁程式p1,p2,…,pm。如果想要在軟體中應用第pi號補丁程式,則軟體中必須存在錯誤B+i ≤B,並且錯誤B-i≤B必須不存在(顯然,B+i∩B-i為空白集)。然後,這個補丁程式將改正錯誤 F-i≤B(如果錯誤存在的話),並且產生新錯誤F+i≤B(同樣,F+i∩F-i也為空白集)。現在,微硬公司的問題只有一個。他們給出一個原始版本的軟體,軟體包含了B中的所有錯誤,然後按照某一順序在軟體中應用補丁程式(應用某個補丁程式時,軟體必須符合該補丁程式的應用條件,且運行該程式需要一定的時間)。問怎樣才能最快地改正軟體中的所有錯誤(即為修正所有錯誤而啟動並執行補丁程式的總時間最短)? 【輸入格式】資料存放在目前的目錄下的文字檔“bugs.in"中。檔案的第一行包含兩個整數n和m,分別表示軟體中的錯誤個數和發送的補丁個數。其中,n和m滿足條件:1≤n≤20,1≤m≤100。接下來的m行(即第2行至第m+1行)按順序描述了m個補丁程式的情況,第i行描述第i-1號補丁程式。每一行包含一個整數(表示在軟體中應用該補丁程式所需的時間,單位為秒)和兩個n個字元的字串(中間均用一個空格分開)。、第一個字串描述了應用該補丁程式(第i-1號)的條件,即說明在軟體中某錯誤應該存在還是不應該存在。字串的第i個字元,如果是“+”,表示在軟體中必須存在bi號錯誤;如果是“-”,表示軟體中錯誤bi不能存在;如果是“0",則表示錯誤bi存在或不存在均可(即對應用該補丁程式沒有影響)。第二個字串描述了應用該補丁程式(第i-1號)後的效果,即應用補丁程式後,哪些錯誤被修改好了,而又產生了哪些新錯誤。字串的第i個字元,如果是“+”,表示產生了一個新錯誤bi;如果是“-”,表示錯誤bi被修改好了;如果是“0”,則表示錯誤bi不變(即原來存在,則仍然存在;原來不存在,則也不存在)。 【輸出格式】答案輸出在目前的目錄下的文字檔“bugs.out"中。請你找到一個應用補丁程式的最優順序,修改軟體中的所有錯誤,並且所用的時間最少。注意,每個補丁程式是可以應用多次的。如果存在這樣一個序列,請在輸出檔案的第一行輸出應用補丁程式的總時間(單位為秒);如果找不到這樣一個序列,請在輸出檔案的第一行輸出-1。 【輸入輸出範例】範例輸入(bugs.in):3 31 000 00-1 00- 0-+2 0-- -++範例輸出(bugs.out):8
這題其實不是網路流。
狀態壓縮表示各個bug的存在狀態,求從1111111到0000000的最短路徑。
不需要顯式建邊(也建不下)
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<algorithm> 5 #include<queue> 6 #define LL long long 7 using namespace std; 8 const int INF=1e9; 9 const int mxm=1<<21;10 const int mxn=110;11 int n,m;12 int dis[mxm];13 struct pk{14 int q,c;//必須存在的錯誤,不能存在的錯誤15 int k1,k2;//修複效果16 int w;17 }a[mxn];18 bool inq[mxm];19 bool pd(int x,int y){//判斷補丁可否應用20 if((x|a[y].q)!=x)return 0;21 if((x&a[y].c))return 0;22 return 1;23 }24 void Spfa(){25 memset(dis,0x3f,sizeof dis);26 queue<int>q;27 q.push(n);28 dis[n]=0;29 while(!q.empty()){30 int u=q.front();q.pop();inq[u]=0;31 for(int i=1;i<=m;i++){32 if(pd(u,i)){33 int v=(u^(u&a[i].k2))|a[i].k1;34 if(dis[v]>dis[u]+a[i].w){35 dis[v]=dis[u]+a[i].w;36 if(!inq[v]){37 inq[v]=1;38 q.push(v);39 }40 }41 }42 }43 }44 return;45 }46 int main(){47 freopen("bugs.in","r",stdin);48 freopen("bugs.out","w",stdout);49 int i,j;50 scanf("%d%d",&n,&m);51 char s[30];52 for(i=1;i<=m;i++){53 scanf("%d%s",&a[i].w,s);54 for(j=0;j<n;j++){55 if(s[j]==‘+‘) a[i].q|= (1<<j);56 if(s[j]==‘-‘) a[i].c|= (1<<j);57 }58 scanf("%s",s);59 for(j=0;j<n;j++){60 if(s[j]==‘+‘) a[i].k1|= (1<<j);61 if(s[j]==‘-‘) a[i].k2|= (1<<j);62 }63 }64 n=(1<<n)-1;65 Spfa();66 if(dis[0]!=0x3f3f3f3f)printf("%d\n",dis[0]);67 else printf("-1\n");68 return 0;69 }
COGS439. [網路流24題] 軟體補丁