题目链接:点击查看

题目大意:给出 n 个工人,再给出 m 台机器,第 i 个工人和第 j 台机器匹配的代价是 a[ i ] * j * j + b[ i ] * j + c[ i ] ,问如何进行匹配,可以使得代价和最小

题目分析:代价可以视为二次函数,且数据范围限制了系数 a 是大于 0 的,换句话说,二次函数的开口向上,这样函数就存在着最小值

考虑 n 最大只有 50 ,所以我们可以对于每个工人的二次函数,求出与其匹配所花费代价的前 n 小的位置,求出这些位置之后,直接将工人与机器连边求解就好了,因为每个工人都与 n 个机器建边,所以最终一定可以达到完全匹配,最终有 n 个工人,n * n 台机器,而 spfa 实现的费用流总时间复杂度会退化为 n^5 ,但常数较小,跑起来还是非常快的

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=3e3+100;//点const int M=5e5+100;//边LL res[60],a[60],b[60],c[60];vector<int>node[60];//每个i的前n小的位置 vector<int>ve;//离散化 struct Edge
{int to,w,next;LL cost;
}edge[M];int head[N],cnt;void addedge(int u,int v,int w,LL cost)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].cost=cost;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=0;edge[cnt].cost=-cost;edge[cnt].next=head[v];head[v]=cnt++;
}LL d[N];int incf[N],pre[N];bool vis[N];bool spfa(int s,int t)
{memset(d,0x3f,sizeof(d));memset(vis,false,sizeof(vis));memset(pre,-1,sizeof(pre));queue<int>q;q.push(s);vis[s]=true;incf[s]=inf;d[s]=0;while(!q.empty()){int u=q.front();q.pop();vis[u]=false;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;LL cost=edge[i].cost;if(!w)continue;if(d[v]>d[u]+cost){d[v]=d[u]+cost;pre[v]=i;incf[v]=min(incf[u],w);if(!vis[v]){vis[v]=true;q.push(v);}}}}return pre[t]!=-1;
}LL update(int s,int t)
{int x=t;while(x!=s){int i=pre[x];edge[i].w-=incf[t];edge[i^1].w+=incf[t];x=edge[i^1].to;}return d[t]*incf[t];
}void init()
{ve.clear();for(int i=0;i<60;i++)node[i].clear(); memset(head,-1,sizeof(head));cnt=0;
}void solve(int st,int ed)
{LL ans=0;int tot=0;while(spfa(st,ed)){ans+=update(st,ed);res[++tot]=ans;}
}LL fun(int i,int x)
{return a[i]*x*x+b[i]*x+c[i];
}void discreate()
{sort(ve.begin(),ve.end());ve.erase(unique(ve.begin(),ve.end()),ve.end());
}int get_num(int x)
{return lower_bound(ve.begin(),ve.end(),x)-ve.begin()+1;
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){init();int n,m,st=N-1,ed=st-1;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%lld%lld%lld",a+i,b+i,c+i);int pos=-(b[i]/(a[i]*2));//对称轴pos=min(pos,m);pos=max(pos,1);for(int j=pos,cnt=0;j>=1&&cnt<=n;j--,cnt++)//往前找n个 node[i].push_back(j);for(int j=pos+1,cnt=0;j<=m&&cnt<=n;j++,cnt++)//往后找n个 node[i].push_back(j);sort(node[i].begin(),node[i].end(),[&](int x,int y)//排序 {return fun(i,x)<fun(i,y);});node[i].resize(n);//只保留前n大 for(auto it:node[i])ve.push_back(it);}discreate();for(int i=1;i<=ve.size();i++)addedge(i+n,ed,1,0);for(int i=1;i<=n;i++){addedge(st,i,1,0);for(auto it:node[i]){int pos=get_num(it);addedge(i,pos+n,1,fun(i,it));}}solve(st,ed);for(int i=1;i<=n;i++)printf("%lld%c",res[i],i==n?'\n':' ');}return 0;
}

HDU多校2 - 6767 New Equipments(最小费用最大流)相关推荐

  1. 2020杭电多校(二) New Equipments(最小费用最大流)

    New Equipments 思路 数据已经有提示了b∗b<=4∗a∗cb * b <= 4 * a * cb∗b<=4∗a∗c,这意味着,每一个a,b,ca, b, ca,b,c构 ...

  2. HDU 2282 Chocolate (最小费用最大流)

    HDU  2282 Chocolate (最小费用最大流) #include <iostream> #include <cstdio> #include <queue&g ...

  3. HDU 1853 HDU 3488【有向环最小权值覆盖问题 】最小费用最大流

    HDU 1853 & HDU 3488[有向环最小权值覆盖问题 ]带权二分图匹配 KM算法 In the kingdom of Henryy, there are N (2 <= N & ...

  4. 牛客多校 - Minimum-cost Flow(最小费用最大流+贪心)

    题目链接:点击查看 题目大意:给出一张有向图,每条边都有单独的花费,现在给出 q 次询问,每次询问给出一个 u 和 v 需要回答:将所有边的流量都设置为 u / v 后,从点 1 到点 n 流量为 1 ...

  5. 【HDU - 6118】度度熊的交易计划(最小费用可行流,网络流费用流变形 )

    题干: 度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个片区能够花费a[i]元生产1个 ...

  6. hdu Kaka's Matrix Travels(最小费用最大流)

    把题意写一下:  给你一个n*n的矩阵,每个格子都有一个非负整数,从左上角走到右下角,收集走过的数字,累加,但是只能向右或者向下走,走过之后数字就变为0,让你求从左上角到右下角,走k次之后,所得的最大 ...

  7. HDU 6445 Search for Answer(最小费用最大流-mcmf)

    Description 给出一个nnn个点的完全图的邻接矩阵aaa,其中ai,j=1a_{i,j}=1ai,j​=1表示i,ji,ji,j之间边的方向是iii到jjj,ai,j=0a_{i,j}=0a ...

  8. Going Home HDU - 1533 (最小费用最大流)

    题目链接:https://cn.vjudge.net/problem/HDU-1533 题意:给你n个房子n个人  使得所有人都有一座房子的最小花费 思路:把所有的人与房子建边,最后,源点与所有的人建 ...

  9. HDU5900 QSC and Master(区间DP + 最小费用最大流)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...

最新文章

  1. Hexo+腾讯云COS,为你的站点加速
  2. 虚拟机的联网模式正确的选择
  3. 解决 Illegal DefaultValue null for parameter type integer 异常
  4. 深入探究Spark -- 了解Executor和参数配置
  5. 批处理(定时器) ssm spring-task
  6. MySQL中的索引(普通索引篇)
  7. python监视键盘_关于键盘监视的库pyHook与pythoncom
  8. 使用VSCode连接到IBM Cloud区块链网络
  9. 户外lisp导向牌如何安装_聚焦热点、难点,持续开展户外广告(招牌)专项整治...
  10. 记IOS8中碰到的一个JS bug
  11. php 实时监测网站是否异常_网站跳转劫持解决,网站跳转劫持解决方法只有3步...
  12. MXNet的Model API
  13. Python: 序列list:保持元素顺序同时消除重复值
  14. 无线网卡没有linux驱动,ubuntu18.04没有无线网卡驱动怎么办?
  15. matlab里怎么做能带结构图,用matlab画出石墨烯的能带关系图Homewo.PDF
  16. 建立SIP软电话环境
  17. python got an unexpected keyword argument
  18. 利用多拨技术将100M宽带免费扩展到1000M
  19. 苹果Macbook电脑无法进入系统
  20. Android 百度地图api 问题 汇总

热门文章

  1. 解决方案 | python安装wordfreq库
  2. 同样的sql在两个oracle,sql – 从两个会话INSERT到唯一列相同的值(Oracle)
  3. 初识Caffeine
  4. SpringBoot maxConnections、maxThreads、acceptCount解析
  5. ConcurrentHashMap的源码分析-高低位原理分析
  6. 锁的释放流程-ReentrantLock.unlock
  7. 函数式接口作为方法的参数【应用】
  8. 缓存-SpringCache-原理与不足
  9. 类加载的双亲委派机制
  10. Spring的@Configuration配置类-Full和Lite模式