博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 2039人员雇佣
阅读量:7120 次
发布时间:2019-06-28

本文共 2645 字,大约阅读时间需要 8 分钟。

  这道题教会我一个道理靠谁也不如靠自己。

  当时学长已经讲了,然而一脸懵逼,好吧,上网搜题解,二脸懵逼,于是自己动手,丰衣足食。自己推!

  首先就是建模了,这道题谁与谁之间建模已经十分明了,超级源点,超级汇点没跑,重点在权值,首先,依照题意,是“舍弃”,因此基本确认为最小割,那么最小割从哪里割,就是我们每个人都雇佣所赚的钱(由样例可知,实际上是2倍所赚的钱,以下省略“*2”,简称合作金),但先不必算雇佣金,在一开始先只考虑赚钱,那么先说最简单的,两个人都雇佣,那么我们所赚的钱为两人合作金-雇佣两人所花的钱,那么我们割掉的边的流量就应当是雇佣金了,于是乎,连向终点的流量get,即为雇佣金。

  于是我们happy的继续推,如果这两个人我都不雇佣,那么我损失的就是雇佣他俩所赚的钱了,而我割的边的流量就是合作金,因为两人均摊,因此不必*2。

  最后,也就是个人认为比较复杂的就是一个雇佣一个不雇佣的情况,那么比起两人一起合作所产生的合作金我少的就是两倍合作金+敌对公司让我减少的一倍合作金+我所雇佣的那个人的雇佣金,由之前我们可知我割掉雇佣的那个人与汇点的时候已减少雇佣金,我割掉不雇佣的人与源点的时候以减去一倍合作金,于是乎,剩下的就是两倍合作金了,这就是两人之间的流量,记得开双向哈。

  总的来说就是这样,由简到难,由已知边的流量去推未知边的流量,找准总值为关键,实在不行就列个方程,怎样也能搞出来。

 

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 using namespace std; 9 int n,s,zz=1,t; 10 long long co[1015],a[1015]; 11 struct ro{ 12 int to,from; 13 int next; 14 long long l; 15 }road[9000000]; 16 void build(int x,int y,long long z){ 17 zz++; 18 road[zz].l=z; 19 road[zz].to=y; 20 road[zz].from=x; 21 road[zz].next=a[x]; 22 a[x]=zz; 23 zz++; 24 road[zz].to=x; 25 road[zz].from=y; 26 road[zz].next=a[y]; 27 road[zz].l=0; 28 a[y]=zz; 29 } 30 long long sum[1005]; 31 long long deep[1005],cur[1015],cur2[1015]; 32 bool bfs(){ 33 memset(deep,0,sizeof(deep)); 34 queue
q1; 35 q1.push(s); 36 deep[s]=1; 37 while(!q1.empty()) 38 { 39 int x=q1.front(); 40 q1.pop(); 41 for(int i=a[x];i>0;i=road[i].next) 42 { 43 int y=road[i].to; 44 if(road[i].l>0&&(!deep[y])) 45 { 46 deep[y]=deep[x]+1; 47 q1.push(y); 48 } 49 } 50 } 51 if(!deep[t])return 0; 52 return 1; 53 } 54 long long dfs(int x,long long sum){ 55 if(x==t||!sum) return sum; 56 for(int i=cur[x];i>0;i=road[i].next) 57 { 58 cur[x]=i; 59 int y=road[i].to; 60 if(road[i].l>0&&deep[y]==deep[x]+1) 61 { 62 int k=dfs(y,min(sum,road[i].l)); 63 if(k) 64 { 65 road[i].l-=k; 66 road[i^1].l+=k; 67 return k; 68 } 69 } 70 } 71 return 0; 72 } 73 long long work(){ 74 long long ans=0; 75 memcpy(cur2,a,sizeof(a)); 76 while(bfs()) 77 { 78 int x; 79 memcpy(cur,cur2,sizeof(cur2)); 80 while(x=dfs(s,0x7fffffff)) 81 { 82 ans+=x; 83 } 84 } 85 return ans; 86 } 87 long long summ; 88 int main(){ 89 scanf("%d",&n); 90 t=n+1; 91 for(int i=1;i<=n;i++) 92 { 93 scanf("%lld",&co[i]); 94 } 95 for(int i=1;i<=n;i++) 96 { 97 for(int j=1;j<=n;j++) 98 { 99 long long x;100 scanf("%lld",&x);101 if(x)build(i,j,x*2);102 sum[i]+=x;103 }104 }105 for(int i=1;i<=n;i++)106 {107 build(s,i,sum[i]);108 build(i,t,co[i]);109 summ+=sum[i];110 }111 printf("%lld\n",summ-work());112 //while(1);113 return 0;114 }

 

转载于:https://www.cnblogs.com/liutianrui/p/7265808.html

你可能感兴趣的文章
【跃迁之路】【716天】程序员高效学习方法论探索系列(实验阶段473-2019.2.6)...
查看>>
区块链安全的奥秘之一:非对称加密
查看>>
Salesforce平台支持多租户Multi tenant的核心设计思路
查看>>
最佳在线图表软件
查看>>
手挽手带你学React:三档 React-router4.x的使用
查看>>
React Hooks 梳理
查看>>
垃圾回收之引用计数
查看>>
Java的Interrupt与线程中断
查看>>
前端实用小工具
查看>>
大型云原生项目在数字化企业落地过程解密
查看>>
CentOS 7 编译安装 PHP 7
查看>>
vue跳转传参刷新后参数消失
查看>>
Java™ 教程(原子变量)
查看>>
非对称加密算法--RSA加密原理及运用
查看>>
精读《如何编译前端项目与组件》
查看>>
[ 逻辑锻炼] 用 JavaScript 做一个小游戏 ——2048 (详解版)
查看>>
【产品】产品经理常用的五大分析法
查看>>
Javascript二进制运算符的一些运用场景
查看>>
常见Promise面试题
查看>>
一个专科生学习JAVA目标月薪2万是否不切实际?
查看>>