POJ 2987 Firing【最大权闭合图-最小割】

题意:给出一个有向图,选择一个点,则要选择它的可以到达的所有节点。选择每个点有各自的利益或损失。求最大化的利益,以及此时选择人数的最小值。

算法:构造源点s汇点t,从s到每个正数点建边,容量为利益。每个负点到t建边,容量为损失的绝对值。其他关系边容量正向无穷,反向0。正数点总和减去最小割即为最大权闭合图答案。因为残余网络不会对0流边处理,所以不会将0流点选入取点集,所以最小割的取法中为被选中的点。

最大权闭合图的求解方法:

  1. 先构造网络流N,添加源点s,从s到正权值点做一条边,容量为点的权值。

  2. 添加汇点t,从负权值点到t做一条边,容量为点的权值的绝对值。

  3. 原来的边的容量统统设为无穷大。比如:

    转换为

  4. 求解最小割:最大权=正权值之和-最小割权值

  5. 残余网络中的点的个数即为裁员个数。

思路:最大权闭合图。用Dinic求最小割

要得到最大收益,就是尽量选择更多收益为正数的人,选择更少收益为负数的人,因此我们将收益为正数的人与源点连一条边,将收益为负数的人与汇点连一条边,这样得到的割集就是未选择的收益为正数的人+选择的收益为负数的人(也可以是损失的收益),要使这个割集越小越好,那么就是求最小割。最大收益是所有正数的和sum,再用sum-最小割(损失的收益)就可以得到最大收益。

最少的裁员人数,最小割后的的残余网络中,只要能从S遍历到的点,就可以看成是被裁掉的点,因为最终肯定会遇到割边达不到T,所以我们直接DFS残余网络的点数就可以得到最少的裁员人数了。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <queue>
  5 #include <vector>
  6 using namespace std;
  7 typedef long long LL;
  8 
  9 const LL INF = 0x3f3f3f3f3f3f3f3f;
 10 
 11 struct edge
 12 {
 13     edge(int _v,int _r, LL _c):v(_v),r(_r),c(_c){};
 14     int v,r;
 15     LL c;
 16 };
 17 
 18 vector<edge> e[5010];
 19 
 20 void add_edge(int u,int v,LL c)
 21 {
 22     e[u].push_back(edge(v,e[v].size(),c));
 23     e[v].push_back(edge(u,e[u].size()-1,0));
 24 }
 25 
 26 int level[5010];
 27 int iter[5010];        // 当前弧,在其之前的边已经没有用了
 28 queue<int> q;
 29 
 30 bool bfs(int s,int t)
 31 {
 32     memset(level,0, sizeof(level));
 33     while (!q.empty()) q.pop();
 34     q.push(s);
 35     level[s]=1;
 36     while(!q.empty())
 37     {
 38         int u=q.front();q.pop();
 39         for(int i=0;i<e[u].size();i++)
 40         {
 41             int v=e[u][i].v;
 42             if(e[u][i].c>0&&!level[v])
 43             {
 44                 q.push(v);
 45                 level[v]=level[u]+1;
 46             }
 47             if(level[t])return 1;
 48         }
 49     }
 50     return 0;
 51 }
 52 
 53 LL dfs(int s,int t, LL flow)
 54 {
 55     if(s==t)return flow;
 56     for(int& i = iter[s];i<e[s].size();i++) // 一次增广返回时,记录当前弧
 57     {
 58         int v = e[s][i].v;
 59         if(e[s][i].c>0&&level[v]==level[s]+1)
 60         {
 61             LL k = dfs(v,t,min(flow,e[s][i].c));
 62             if(k>0)
 63             {
 64                 e[s][i].c-=k;
 65                 e[v][e[s][i].r].c+=k;
 66                 return k;
 67             }
 68         }
 69     }
 70     return 0;
 71 }
 72 
 73 LL Dinic(int s,int t)
 74 {
 75     LL flow=0;
 76     while(bfs(s,t))
 77     {
 78         LL f=0;
 79         memset(iter, 0, sizeof(iter));
 80         while((f=dfs(s,t,INF))>0)flow+=f;
 81     }
 82     return flow;
 83 }
 84 
 85 bool vis[5010];
 86 int cnt;
 87 void GaoCnt(int u)//dfs统计残余图的正边
 88 {
 89     ++cnt;
 90     vis[u]=1;
 91     for(int i=0;i<e[u].size();i++)
 92     {
 93         int v=e[u][i].v;
 94         if(e[u][i].c>0&&!vis[v])
 95             GaoCnt(v);
 96     }
 97 }
 98 
 99 
100 int main()
101 {
102     int n,m;
103     scanf("%d%d",&n,&m);
104     int s=0,t=n+1;// 源点,汇点
105     LL ans=0;
106     for(int i=1;i<=n;i++)
107     {
108         LL c;
109         scanf("%lld",&c);
110         if(c>0)
111         {
112             ans+=c; //正权值求和
113             add_edge(s,i,c);
114         }
115         else if(c<0)
116         {
117             add_edge(i,t,-c);
118         }
119     }
120     for (int i = 0; i < m; ++i) {
121         int u,v;
122         scanf("%d%d",&u,&v);
123         add_edge(u,v,INF);
124     }
125     ans-= Dinic(s,t);
126     GaoCnt(s);
127     printf("%d %lld\n",cnt-1,ans);
128     return 0;
129 }

参考自:hankcsyogykwan

转载于:https://www.cnblogs.com/demian/p/9234825.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容介绍 项目结构: Controller层:使用Spring MVC来处理用户请求,负责将请求分发到相应的业务逻辑层,并将数据传递给视层进行展示。Controller层通常包含控制器类,这些类通过注解如@Controller、@RequestMapping等标记,负责处理HTTP请求并返回响应。 Service层:Spring的核心部分,用于处理业务逻辑。Service层通过接口和实现类的方式,将业务逻辑与具体的实现细节分离。常见的注解有@Service和@Transactional,后者用于管理事务。 DAO层:使用MyBatis来实现数据持久化,DAO层与数据库直接交互,执行CRUD操作。MyBatis通过XML映射文件或注解的方式,将SQL语句与Java对象绑定,实现高效的数据访问。 Spring整合: Spring核心配置:包括Spring的IOC容器配置,管理Service和DAO层的Bean。配置文件通常包括applicationContext.xml或采用Java配置类。 事务管理:通过Spring的声明式事务管理,简化了事务的处理,确保数据一致性和完整性。 Spring MVC整合: 视解析器:配置Spring MVC的视解析器,将逻辑视名解析为具体的JSP或其他类型的视。 拦截器:通过配置Spring MVC的拦截器,处理请求的预处理和后处理,常用于权限验证、日志记录等功能。 MyBatis整合: 数据源配置:配置数据库连接池(如Druid或C3P0),确保应用可以高效地访问数据库。 SQL映射文件:使用MyBatis的XML文件或注解配置,将SQL语句与Java对象映射,支持复杂的查询、插入、更新和删除操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值