洛谷P2762 太空飞行计划问题(最小割)

传送门

 

我们可以把实验放在左边,仪器放在右边,点有点权,然后连对应的有向边,就是求一个最大权闭合图,可以转化为最小割来做(关于这具体是个啥……可以百度胡伯涛《最小割模型在信息学竞赛中的应用》)

总而言之,就是求一个图,每一个点有点权,闭合图就是若图中有点$u$,且原图中存在边$(u,v)$,那么点$v$也在图中。然后求一个最大权的闭合图即可(具体证明看上面)。最大权闭合图可以转化成下面那样建图之后求最小割

源点向所有实验连边,容量为收益,实验向对应仪器连边,容量为$inf$,仪器向汇点连边,容量为花费,求一个最小割就好了,然后答案就是收益总和减去最小割

然后考虑怎么求方案,因为最后一次bfs没有增广成功,而与源点想通的点就是闭合图中的点,所以只要最后一次分层图中$dep$不等于$-1$的点即可

 1 //minamoto
 2 #include<cstdio>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<queue>
 6 #define inf 0x3f3f3f3f
 7 using namespace std;
 8 inline bool read(int &res){
 9     res=0;char ch=getchar();
10     while(!isdigit(ch)){if(ch=='\n') return false;ch=getchar();}
11     while(isdigit(ch)){res=res*10+ch-'0',ch=getchar();}
12     return ch!='\n';
13 }
14 const int N=105,M=10005;
15 int ver[M],Next[M],head[N],edge[M],cur[N],tot=1;
16 int dep[N],n,m,s,t,ans;
17 queue<int> q;
18 inline void add(int u,int v,int e){
19     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
20     ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=0;
21 }
22 bool bfs(){
23     memset(dep,-1,sizeof(dep));
24     for(int i=0;i<=n+m+1;++i) cur[i]=head[i];
25     q.push(s),dep[s]=0;
26     while(!q.empty()){
27         int u=q.front();q.pop();
28         for(int i=head[u];i;i=Next[i]){
29             int v=ver[i];
30             if(dep[v]<0&&edge[i])
31             dep[v]=dep[u]+1,q.push(v);
32         }
33     }
34     return ~dep[t];
35 }
36 int dfs(int u,int limit){
37     if(!limit||u==t) return limit;
38     int flow=0,f;
39     for(int i=cur[u];i;i=Next[i]){
40         int v=ver[i];cur[u]=i;
41         if(dep[v]==dep[u]+1&&(f=dfs(v,min(limit,edge[i])))){
42             flow+=f,limit-=f;
43             edge[i]-=f,edge[i^1]+=f;
44             if(!limit) break;
45         }
46     }
47     return flow;
48 }
49 int dinic(){
50     int flow=0;
51     while(bfs()) flow+=dfs(s,inf);
52     return flow;
53 }
54 int main(){
55     scanf("%d%d",&m,&n);
56     s=0,t=n+m+1;
57     for(int i=1,x;i<=m;++i){
58         scanf("%d",&x),ans+=x;
59         add(s,i,x);
60         while(read(x)) add(i,x+m,inf);
61         add(i,x+m,inf);
62     }
63     for(int i=m+1,x;i<=n+m;++i){
64         scanf("%d",&x);
65         add(i,t,x);
66     }
67     ans-=dinic();
68     for(int i=1;i<=m;++i)
69     if(~dep[i]) printf("%d ",i);
70     putchar(10);
71     for(int i=m+1;i<=n+m;++i)
72     if(~dep[i]) printf("%d ",i-m);
73     putchar(10);
74     printf("%d\n",ans);
75     return 0;
76 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9502032.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值