• 网络流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 */
  • 相关阅读:
    白话算法(6) 散列表(Hash Table)从理论到实用(中)
    白话算法(6) 散列表(Hash Table) 从理论到实用(下)
    基于无锁的C#并发队列实现
    邻接表建图的三种方式的时空比较(解析+图示)
    Windows内存管理(1)--分配内核内存 和 使用链表
    Windows内存管理(2)--Lookaside结构 和 运行时函数
    error C2443: operand size conflict
    CPUID 指令的使用
    Windows内核驱动开发入门学习资料
    重载内核全程分析笔记
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7448306.html
Copyright © 2020-2023  润新知