Codeforces 题面传送门 & 洛谷题面传送门

好久没有写过上下界网络流了,先来一题再说(

首先先假设所有边都是蓝边,那么这样首先就有 \(b\times m\) 的花费,但是这样不一定符合条件,就算符合条件也不一定是最优解,因此需要调整。

显然一个点与其相连的边中,红边与蓝边的大小关系可用 \(b-r\) 来衡量,其中 \(b,r\) 分别表示与其相连的蓝边、红边的数量。我们考虑一个反悔贪心的思想,考虑将一条蓝边变成红边会对 \(b-r\) 产生怎样的影响,显然这可以分为两个阶段,一是蓝 \(\to\) 无的阶段,\(b-r\) 的值减一,而是无 \(\to\) 红的阶段,\(b-r\) 的值再次减一。因此考虑用两条边表示这两个阶段,一是 \(u\to v\),容量 \(1\) 费用 \(-b\) 的边,表示蓝 \(\to\) 无的阶段,而是 \(u\to v\),容量 \(1\) 费用 \(r\) 的边,表示无 \(\to\) 红的阶段。由于我们要求最小费用,因此对于两条重边,我们肯定会优先选费用小的走,即费用 \(-b\) 的边,符合我们的建图方式。而经我们这么一建图,一个点的 \(b-r\) 就很好表示了:就是该点的度减去经过该点的流的条数。接下来考虑一个点的限制,对于红点 \(x\),它的 \(b-r\) 应 \(<0\),因此经过它的流的条数应 \(>deg_x\),因此如果它在左部,我们就连边 \((S,x,deg_x+1,2deg_x,0)\),如果它在右部,我们就连边 \((x,T,deg_x+1,2deg_x,0)\)。对于蓝点 \(x\),它的 \(b-r\) 应 \(>0\),因此经过它的流的条数应 \(<deg_x\),因此我们只用把上面连的边中 \((deg_x+1,2deg_x)\) 全部换成 \((0,deg_x-1)\) 即可。对于无色点显然没有任何限制,直接连 \((0,2deg_x)\) 的边即可。然后跑最小费用可行流,答案就是费用 \(+bm\)。

直接跑会出现负环,因为在最小费用可行流中我们连了 \(T\to S\) 的边,而这条边与中间我们连的费用为 \(-b\) 的边构成了大小为 \(-b\) 的环,因此需要消圈。具体消圈方法就是假设负权边满流,然后按照上下界网络流的套路建立虚拟源汇然后连相应的边调整流量即可。

时间复杂度 \(\mathcal O(\text{能过})\)。

const int MAXN=200;
const int MAXV=404;
const int MAXE=5000;
int n1,n2,m,r,b,deg[MAXV+5];char s1[MAXN+5],s2[MAXN+5];
int S1,S2,T1,T2,hd[MAXV+5],to[MAXE+5],nxt[MAXE+5],cst[MAXE+5],cap[MAXE+5],ec=1;
void adde(int u,int v,int f,int c){
if(f<0) puts("-1"),exit(0);
// printf("%d %d %d %d\n",u,v,f,c);
to[++ec]=v;cap[ec]=f;cst[ec]=c;nxt[ec]=hd[u];hd[u]=ec;
to[++ec]=u;cap[ec]=0;cst[ec]=-c;nxt[ec]=hd[v];hd[v]=ec;
}
int sum_has,sum_cst;
void _adde(int u,int v,int l,int r,int c){
adde(u,v,r-l,c);adde(S2,v,l,0);adde(u,T2,l,0);
sum_has+=l;sum_cst+=1ll*l*c;
}
int dis[MAXV+5],lste[MAXV+5],flw[MAXV+5],pre[MAXV+5];
bool inq[MAXV+5];
bool getdis(int S,int T){
memset(dis,63,sizeof(dis));memset(flw,0,sizeof(flw));
dis[S]=0;flw[S]=INF;inq[S]=1;queue<int> q;q.push(S);
while(!q.empty()){
int x=q.front();q.pop();inq[x]=0;
for(int e=hd[x];e;e=nxt[e]){
int y=to[e],z=cap[e],w=cst[e];
if(z&&dis[y]>dis[x]+w){
dis[y]=dis[x]+w;flw[y]=min(flw[x],z);
pre[y]=x;lste[y]=e;
if(!inq[y]) inq[y]=1,q.push(y);
}
}
} return dis[T]<INF;
}
pair<int,int> mcmf(int S,int T){
int mxfl=0,mncst=0;
while(getdis(S,T)){
mncst+=1ll*flw[T]*dis[T];mxfl+=flw[T];
for(int i=T;i^S;i=pre[i]){
cap[lste[i]]-=flw[T];cap[lste[i]^1]+=flw[T];
}
} return mp(mxfl,mncst);
}
int main(){
scanf("%d%d%d%d%d%s%s",&n1,&n2,&m,&r,&b,s1+1,s2+1);
T2=(S2=(T1=(S1=n1+n2+1)+1)+1)+1;
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);v+=n1;
deg[u]++;deg[v]++;adde(v,u,1,b);
adde(S2,v,1,0);adde(u,T2,1,0);
sum_cst-=b;sum_has++;adde(u,v,1,r);
}
for(int i=1;i<=n1;i++){
if(s1[i]=='R') _adde(S1,i,deg[i]+1,deg[i]*2,0);
if(s1[i]=='B') adde(S1,i,deg[i]-1,0);
if(s1[i]=='U') adde(S1,i,deg[i]*2,0);
}
for(int i=1;i<=n2;i++){
if(s2[i]=='R') _adde(i+n1,T1,deg[i+n1]+1,deg[i+n1]*2,0);
if(s2[i]=='B') adde(i+n1,T1,deg[i+n1]-1,0);
if(s2[i]=='U') adde(i+n1,T1,deg[i+n1]*2,0);
} adde(T1,S1,INF,0);
pair<int,int> pr=mcmf(S2,T2);
if(pr.fi!=sum_has) return puts("-1"),0;
int res=sum_cst+pr.se+m*b;
printf("%d\n",res);
for(int i=3,j=1;j<=m;i+=8,j++){
if(cap[i]==1) putchar('B');
else if(cap[i+6]==1) putchar('R');
else putchar('U');
}
return 0;
}

Codeforces 1288F - Red-Blue Graph(上下界网络流)的更多相关文章

  1. ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (上下界网络流)

    正解: #include <bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int MAXN=1 ...

  2. ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (贪心或有源汇上下界网络流)

    "Oh, There is a bipartite graph.""Make it Fantastic."X wants to check whether a ...

  3. ACM-ICPC 2018 沈阳赛区网络预赛 F Fantastic Graph(贪心或有源汇上下界网络流)

    https://nanti.jisuanke.com/t/31447 题意 一个二分图,左边N个点,右边M个点,中间K条边,问你是否可以删掉边使得所有点的度数在[L,R]之间 分析 最大流不太会.. ...

  4. CF#366 704D Captain America 上下界网络流

    CF上的题,就不放链接了,打开太慢,直接上题面吧: 平面上有n个点, 第 i 个点的坐标为 ($X_i ,Y_i$), 你需要把每个点染成红色或者蓝色, 染成红色的花费为 r , 染成蓝色的花费为 b ...

  5. HDU 4940 Destroy Transportation system(无源汇上下界网络流)

    Problem Description Tom is a commander, his task is destroying his enemy’s transportation system. Le ...

  6. 沈阳网络赛 F - 上下界网络流

    "Oh, There is a bipartite graph.""Make it Fantastic." X wants to check whether a ...

  7. hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )

    题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到 ...

  8. 算法笔记--最大流和最小割 && 最小费用最大流 && 上下界网络流

    最大流: 给定指定的一个有向图,其中有两个特殊的点源S(Sources)和汇T(Sinks),每条边有指定的容量(Capacity),求满足条件的从S到T的最大流(MaxFlow). 最小割: 割是网 ...

  9. POJ 2396 Budget(有源汇上下界网络流)

    Description We are supposed to make a budget proposal for this multi-site competition. The budget pr ...

随机推荐

  1. Bootstrap响应式的导航栏

    Bootstrap 导航栏 | 菜鸟教程 <!DOCTYPE html> <html> <head> <meta charset="utf-8&qu ...

  2. Map中getOrDefault()与数值进行比较

    一般用哈希表计数时,value类型通常为Integer.如果想比较某个key出现的次数,使用get(key)与某个数值进行比较是有问题的.当哈希表中并不包含该key时,因为此时get方法返回值是nul ...

  3. 6月2日 Scrum Meeting

    日期:2021年6月2日 会议主要内容概述: 取消账单类别自定义 图表属性分析取消函数输入 增加新的主题模板 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 徐宇 ...

  4. Scrum Meeting 0522

    零.说明 日期:2021-5-22 任务:简要汇报两日内已完成任务,计划后两日完成任务 备注:由于在Beta冲刺阶段的最后一周中团队成员需要准备必修课程计算机网络的相关考试,所以为了保证Beta功能的 ...

  5. [no_code团队]项目介绍 & 需求分析 & 发布预测

    项目 内容 2020春季计算机学院软件工程(罗杰 任健) 博客园班级博客 作业要求 团队项目选择 我们在这个课程的目标是 在团队合作中提升软件开发水平 这个作业在哪个具体方面帮助我们实现目标 进行项目 ...

  6. CentOS系统优化一键配置脚本

    #!/usr/bin/env bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export P ...

  7. GPIO原理与配置(跑马灯,蜂鸣器,按键)

    一.STM32 GPIO固件库函数配置方法 1. 根据需要在项目中删掉一些不用的固件库文件,保留有用的固件库文件 2. 在stm32f10x_conf.h中注释掉这些不用的头文件 3. STM32的I ...

  8. 单片机入门stm32知识学习的先后顺序

    这里大概的罗列了一些学习STM32的内容,以及学习顺序.如果是新手的话,建议边看中文手册和学习视频;如果是已经入门的,个人建议自己做一个项目,不论项目大小,当然里面会涉及到自己已经学习过的,或者是自己 ...

  9. 常用Java API:大数类

    摘要 java中的基础数据类型能存储的最大的二进制数是 2 ^ 63 - 1, 对应的十进制数是9223372036854775807,也就是说只要运算过程中会超过这个数,就会造成数据溢出,从而造成错 ...

  10. 【linux】修改ip后hadoop只有四个节点的问题

    学校的机房,每重启一次就会将虚拟机的某些配置还原到部署到学生机时候的状态(例如.etc/hosts文件中ip与主机名的映射),这个时候与我们前面所部署的hadoop就会产生IP不对应的状态,导致了ha ...