网络流24题——软件补丁问题(最小转移代价)

链接:https://www.oj.swust.edu.cn/oj/problem/show/1747

分析:最多只有20个错误,肯定位操作压缩一下,然后每种状态看做一个点,满足条件的两点连边,求从全错到全对的最短路径即可。一开始疯狂T,后面把模板里加边去掉,直接在增广时判断是否有边,4ms过了。。。以后能不用加边的尽量不用,效率太低了。。

 1 #include<iostream>
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<queue>
 6 using namespace std;
 7 const int maxn=1<<20,INF=1e9;
 8 struct Edge{
 9     int to,len;
10     Edge(int v,int l):to(v),len(l){}
11 };
12 struct Patch{
13     int b1,b2,f1,f2,t;
14 }p[105];
15 int n,m;
16 int dis[maxn];
17 bool inq[maxn];
18 int spfa(){
19     memset(inq,0,sizeof(inq));
20     for(int i=0;i<(1<<n);i++)dis[i]=INF;
21     int u=(1<<n)-1;
22     dis[u]=0;
23     queue<int> Q;
24     Q.push(u);
25     inq[u]=true;
26     while(!Q.empty()){
27         u=Q.front();Q.pop();
28         inq[u]=false;
29         for(int i=0;i<m;i++){
30             if((p[i].b1&u)==p[i].b1&&(p[i].b2&u)==0){
31                 int v=u&(~p[i].f1)|p[i].f2;
32                 if(v==u)continue;
33                 if(dis[v]>dis[u]+p[i].t){
34                     dis[v]=dis[u]+p[i].t;
35                     if(!inq[v]){
36                         Q.push(v);inq[v]=true;
37                     }
38                 }
39             }
40         }
41     }
42     return dis[0];
43 }
44 void read(){
45     string str;
46     for(int i=0;i<m;i++){
47         int k=1;
48         scanf("%d",&p[i].t);
49         cin>>str;
50         for(int j=0;j<str.length();j++){
51             switch(str[j]){
52             case '+':p[i].b1^=k;break;
53             case '-':p[i].b2^=k;break;
54             }
55             k<<=1;
56         }
57         cin>>str;
58         k=1;
59         for(int j=0;j<str.length();j++){
60             switch(str[j]){
61             case '+':p[i].f2^=k;break;
62             case '-':p[i].f1^=k;break;
63             }
64             k<<=1;
65         }
66     }
67 }
68 int main(){
69 //    freopen("e:\in.txt","r",stdin);
70     scanf("%d%d",&n,&m);
71     read();
72     int ans=spfa();
73     if(ans==INF)printf("0
");
74     else printf("%d
",ans);
75     return 0;
76 }
77 
78 /*
79 能不记录图尽量不记录,效率上差超级多!!!
80 用vector记邻接链表,T掉了。。改为不记录的,4ms过。。
81 */
原文地址:https://www.cnblogs.com/7391-KID/p/7448306.html