【loj】#6009. 「网络流 24 题」软件补丁(状态压缩+最短路)

记录一个菜逼的成长。。

题目链接

ps:话说这题跟网络流没关系吧。。

loj的题目有错,第二个字符串里 + 是属于F2,-是属于 F1 .

n 个错,所以一开始的状态是s=(1<<n)1,要使得没有错误,最后的状态就是 t=0 .
然后根据题目的约束条件跑最短路即可。

#include <bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for( int i = l; i <= r; i++ )
#define rep0(i,l,r) for( int i = l; i < r; i++ )
#define ALL(v) (v).begin(),(v).end()
#define cl(a,b) memset(a,b,sizeof(a))
#define clr clear()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int INF = 0x3f3f3f3f;
const int maxn = 100 + 10;
struct Node{
  int b1,b2,f1,f2,w;
}a[maxn];
char str[maxn];
int dis[1<<21],vis[1<<21],n,m;
bool check(int x,int i)
{
  if((x | a[i].b1) != x)return false;//包含b1的所有错误
  if(x & a[i].b2)return false;//不包含b2的所有错误
  return true;
}
int bfs(int s,int t)
{
  queue<int>q;
  q.push(s);
  cl(vis,0),cl(dis,INF);
  vis[s] = 1;dis[s] = 0;
  while(!q.empty()){
    int f = q.front();q.pop();
    vis[f] = 0;
    rep(i,1,m){
      if(check(f,i)){
        int to = (f & (~a[i].f1)) | a[i].f2;
        if(dis[to] > dis[f] + a[i].w){
          dis[to] = dis[f] + a[i].w;
          if(!vis[to]){
            vis[to] = 1;
            q.push(to);
          }
        }
      }
    }
  }
  return dis[t] != INF ? dis[t] : 0;
}
int main()
{
  scanf("%d%d",&n,&m);
  rep(i,1,m){
    scanf("%d%s",&a[i].w,str);
    rep0(j,0,n){
      if(str[j] == '+')a[i].b1 |= (1<<j);
      if(str[j] == '-')a[i].b2 |= (1<<j);
    }
    scanf("%s",str);
    rep0(j,0,n){
      if(str[j] == '+')a[i].f2 |= (1<<j);
      if(str[j] == '-')a[i].f1 |= (1<<j);
    }
  }
  int s = (1<<n) - 1,t = 0 ;
  printf("%d\n",bfs(s,t));
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值