Luogu P14122 [SCCPC 2021] Direction Setting题解 最小费用流

news/2025/10/3 21:20:03/文章来源:https://www.cnblogs.com/Dlyim/p/19125005

P14122 [SCCPC 2021] Direction Setting

题目链接

题目大意

给定一个有n个结点,m条边的无向图,要求给每一条边加上方向,使之变为一个有向图,并使$ D=\sum_{i=0}^{n}max(0,di-ai) $的值最小,其中$ai$是第i个点的限度,$di$是第i个点的入度。

前置知识

最小费用流

分析

对D进行分析可以看出,当$di<=ai$时,顶点i对答案无贡献,否则对答案有$di-ai$的贡献。转换一下,就是每个点都会产生一定的代价,并且每条边都只能指向一个方向,具有流量限度,因此我们可以联想到网络流中的最小费用流。

构图

整个网络流可以分为3层:

第一层:源点→边节点

S → 边i : 容量1, 费用0
含义:每条边提供1个入度资源

第二层:边界点→顶点节点

边i → 顶点u : 容量1, 费用0
边i → 顶点v : 容量1, 费用0
含义:边i可以选择给u或v增加入度

第三层:顶点节点 → 汇点

顶点i → T : 容量a[i], 费用0
顶点i → T : 容量∞, 费用1
含义:前a[i]个入度免费,超出部分每个代价

第一层,源点S中存储整个图的入度总和,因为共有m条边,所以源点的值为m。从S到原图中每一条边都构建一条边,容量为1,费用为0,表示每条边能提供1个入度。第二层,由于原图中的每个边都只能有一个方向,因此让原图中的边向顶点构建容量为1的边,哪条边流满了就代表这条边指向谁。第三层,最关键的一层。每个顶点要向汇点建2条边,因为当$di<=ai$时,顶点i不会产生代价,因此建立一条容量为$ai$,费用为0的边,表示前$ai$个边都是免费的。当$di>ai$时,会产生$di-ai$的代价,由于最后一定会到达汇点,所以容量设为∞,费用为1,流过多少水流就会产生多少代价。

剩下的就是最小费用最大流模板了,可以用SPFA+单路增广来做,具体做法在此不多赘述。

求方向

遍历原图中的每一条边,对于每一条边节点,它在网络流中一定指向两个点节点,只需要看哪个边的容量为0即可,因为每个边节点只提供一个入度,所以流满的那条就是原图中边的方向。

其余细节见代码注释

code

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll N=1010,inf=1e9+7;
ll n,m,_;
ll a[N],ans[N];
ll S,T,mcost;
struct node{ll to,val,cost,nxt;
}e[N*10];
ll h[N],tot;
struct edge{ll u,v;
}s[N];
void add(ll u,ll v,ll w,ll c){e[++tot].to=v;e[tot].val=w;e[tot].cost=c;e[tot].nxt=h[u];h[u]=tot;return;
}
void init(){memset(h,0,sizeof(h));memset(ans,0,sizeof(ans));scanf("%lld%lld",&n,&m);T=m+n+1;tot=1;mcost=0;for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);//存下来原图中的信息 for(ll i=1;i<=m;i++) scanf("%lld%lld",&s[i].u,&s[i].v);/*网络流中各个编号节点所对应的信息:0:源点 1~m:原图中的每一条边m+1~m+n:原图中的每一个点m+n+1:汇点 *///第一层 for(ll i=1;i<=m;i++){add(S,i,1,0);add(i,S,0,0);}//第二层 ll u,v;for(ll i=1;i<=m;i++){u=s[i].u;v=s[i].v;add(i,m+u,1,0);add(m+u,i,0,0);add(i,m+v,1,0);add(m+v,i,0,0);}//第三层 for(ll i=1;i<=n;i++){add(m+i,T,a[i],0);add(T,m+i,0,0);add(m+i,T,inf,1);add(T,m+i,0,-1);}return;
}
bool vis[N<<1];
ll pre[N<<1],pedge[N<<1],dis[N<<1];
//pre[i]:存储网络流中到达节点i的前驱节点 
//pedge[i]:存储从pre[i]到i的边的编号 
bool spfa(){for(ll i=0;i<=T;i++) dis[i]=inf;memset(vis,0,sizeof(vis));queue<ll> q;q.push(S);dis[S]=0;vis[S]=1;ll u,v,w,c;while(q.size()){u=q.front();q.pop();vis[u]=0;for(ll i=h[u];i;i=e[i].nxt){v=e[i].to;w=e[i].val;c=e[i].cost;if(w<=0) continue;if(dis[v]>dis[u]+c){dis[v]=dis[u]+c;pre[v]=u;pedge[v]=i;if(!vis[v]){q.push(v);vis[v]=1;}}}}if(dis[T]==inf) return 0;return 1;
}
void mcmf(){ll now,t;//最小费用流模板 while(spfa()){now=inf;for(ll i=T;i!=S;i=pre[i])now=min(now,e[pedge[i]].val);for(ll i=T;i!=S;i=pre[i]){//增广路 t=pedge[i];e[t].val-=now;e[t^1].val+=now;mcost+=now*e[t].cost;}}printf("%lld\n",mcost);//输出方向 ll u,v,w;for(ll i=1;i<=m;i++){u=s[i].u;for(ll j=h[i];j;j=e[j].nxt){v=e[j].to;w=e[j].val;//网络流中节点m+u就是原图中的节点u if(v==m+u&&w==0){//正向(u→v)时为0,所以只需要判断边是否反向(u←v) ans[i]=1;break;}}}for(ll i=1;i<=m;i++) printf("%lld",ans[i]);putchar('\n');return;
}
int main(){scanf("%lld",&_);while(_--){init();mcmf();}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/926327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

双语网站建设费用网站内页权重怎么查

1、application/x-www-form-urlencoded 最常见 POST 提交数据的方式。 浏览器的原生 form 表单&#xff0c;如果不设置 enctype 属性&#xff0c;那么最终就会以 application/x-www-form-urlencoded 方式提交数据。 <form action"http://www.haha/ads/sds?name小草莓…

做二手钢结构网站二级域名的网站备案

来源&#xff1a;中国基金报在上周最新发射的49颗卫星中&#xff0c;有40颗卫星遭地磁风暴“摧毁”——全球首富、特斯拉CEO马斯克旗下SpaceX公司的星链计划遭遇挫折。此外&#xff0c;美国国家航空航天局(NASA)、亚马逊均表示&#xff0c;对于SpaceX星链计划还要新部署约3万颗…

国内做设备网站哪些好水务公司网站建设方案

使用C语言编写程序对多个数字进行排序输出的操作。 根据提示输入十个数字并按照从小到大的顺序进行输出显示。 效果 完整代码 #include<stdio.h> #define N 10 int main() {int i,j,a[N],temp;printf("请输入 10 个数字&#xff1a;\n");for(i0;i<N;i)s…

苏州资讯网站建设移动商城 网站建设方法方式

Mybatis 多条件查询常见且关键&#xff0c;本文探讨两种方法——Map 传参和 Java Bean 对象传参&#xff0c;展示用法及区别&#xff0c;总结应用场景和优缺点。 1. Map传参方式 原理&#xff1a;Mybatis允许我们通过一个Map对象来传递动态SQL中的参数。Map的键对应于SQL语句中…

南通seo网站诊断Wordpress淘客自动采集

云计算-Linux-计算机硬件组成介绍-Linux系统目录介绍 计算机硬件组成部分 这个感觉就真滴教超级小白了,但是还是讲讲吧 虽然我也感觉在这个地方讲怪怪的 输出设备:鼠标,键盘,触控板 主机设备:主机,CPU,内存,网卡,声卡,显卡 输出设备:屏幕,耳机,打印机 外部存储设备:硬盘,u盘…

大数据变长存储算法 - 实践

大数据变长存储算法 - 实践2025-10-03 21:03 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; …

5 qoj14553 序列与整数对 题解

序列与整数对 题面 给定一个长度为 \(n\) 的正整数序列 \(A_1, A_2, \cdots,A_n\) ,有 \(m\) 次询问,每次给定两个正整数 \(x, y\) ,求有多少个整数对 \((i,j)\) 满足 \(1 \le i < j \le n,A_i = x, A_j = y\)。…

AT_arc064_d [ARC064F] Rotated Palindromes

比较好的题。 首先你考虑一个回文串,什么时候会循环的时候重复计算。当且仅当其有一个最小循环节 \(t\),移动 \(t\) 次后就会相同。 我们要将这种东西给减掉,同样的,这种贡献我们可以在计算长度 \(\le n\) 的回文串…

vscode代码块格式转换器

介绍 在我们使用vscode时,我们会用到代码块。 代码块十分好用,可以帮我们自动补全代码,也可以存各种板子。虽然会损失人的代码能力,但能提升做题效率。但我们注意到,vscode的代码块是使用json编辑的,对于不会jso…

C语言速成秘籍——跳转语句(goto) - 实践

C语言速成秘籍——跳转语句(goto) - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "M…

常州城乡和住房建设厅网站简述建设企业网站可信度的具体策略

作者&#xff1a;vivo 互联网服务器团队- Li Gang 本文介绍了一次排查Dubbo线程池耗尽问题的过程。通过查看Dubbo线程状态、分析Jedis连接池获取连接的源码、排查死锁条件等方面&#xff0c;最终确认是因为使用了cluster pipeline模式且没有设置超时时间导致死锁问题。 一、背…

从免疫原性突破到技术迭代:全人源抗体如何重塑靶向治疗格局?

在治疗性抗体领域,“降低免疫原性” 始终是研发的核心追求 —— 人源化抗体虽通过框架区改造将鼠源序列占比降至 5% 以下(如阿达木单抗),但临床数据显示仍有 3.2% 患者产生抗药抗体(ADA),导致药物清除率提升 50…

实用指南:OpenAI Sora 2重磅发布:AI视频生成进入“GPT-3.5时刻”

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

商业网站的规划和设计linux wordpress 升级

在C语言中&#xff0c;flock 是一个用于文件锁定的函数&#xff0c;定义在 sys/file.h 头文件中。它的主要目的是在对文件进行读写操作时&#xff0c;避免其他进程同时访问文件&#xff0c;以实现文件的并发控制。 flock 函数的原型 #include <sys/file.h>int flock(in…

无锡做网站哪家公司好延庆上海网站建设

题目大意&#xff1a; 有边权点权的树&#xff0c;动态修改点权 每次修改后求带权重心x (\(minimize\) \(S\sum_i val[i]*dist[x][i]\)) 分析&#xff1a; 从暴力找突破口&#xff1a; 对于边x,y&#xff0c;设长度为len&#xff0c;切断后x半边树权值和为\(w_1\)&#xff0c;y…

工作感受月记(202510月)

国庆节在毕节上班一天中...... 2025年10月03号 1/ 值班完成手中TODO list,icm,case,blog,和墨墨记单词270 2/ 整理心态,看queue中 今日关键字:挣钱中

域名就是网站名吗wordpress 消息推送

这里将介绍如何使用 OpenCV 与 Python 来作彩色影像转HSV(RGB to HSV 或 BGR to HSV)&#xff0c;在写 Python 影像处理程序时常会用到 OpenCV cvtColor 作颜色空间转换的功能&#xff0c;接下来介绍怎么使用 Python 搭配 OpenCV 模块来进行 RGB/BGR 转 HSV 彩色转HSV空间。 H…

欧几里得算法与扩展欧几里得算法详解

在数论和密码学中,欧几里得算法(Euclidean Algorithm)是一个古老而重要的算法,用于计算两个整数的最大公约数(GCD)。 欧几里得算法(更相减损法) 欧几里得算法基于以下原理:两个整数的最大公约数等于其中较小的…

网站承建乐山网站公众号建设

前置操作 如果是在 spring-config 中添加 bean 标签来注册内容&#xff0c;每个类都要弄一次就显得麻烦和臃肿了&#xff0c;对于 new 操作而言就没有什么优势了。因此 spring 就引入了注解操作来实现对 Bean 对象的存储。 配置扫描路径 想要将对象成功的存储到 Spring 中&…