题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6667

题目大意是说n个班级,每个班级有ai人和bi杯茶,每个人只能喝其他班的茶并且只能喝一杯。问最多有多少人可以喝茶。

读完题就觉得是网络流or二分图,然后发现数据范围就萎了,开始想怎么转化模型,因为题目实际就是求每个人连其他班的茶之后跑二分图最大匹配。

然后想到了hall定理和推论,好像对于线性求解二分图蛮有帮助的,公式写出来大致就可以明白了。

PS:|X|为点集X的点数

hall定理:

二分图G中的两部分顶点集合分别为X, Y,假设有 |X|<=|Y|。G图存在完美匹配的充分必要条件是:X中的任意k个点至少与Y中的k个点相邻,即对于X中的一个点集W ,令N(W)为W所连的点, 霍尔定理即对于任意W有 |W|<=|N(W)|

推论为:

二分图的最大匹配为:$|X|-max\left \{|W|-|N(W)|\right \}$,其中W为X的任意子集。

对于这题而言设X为学生,Y为茶,则有两种情况:

当子集W中学生为同一班级时,N(W)为|Y|-该班级的茶数。

当自己W中学生不为同一班级时,N(W)为|Y|。

所以暴力跑O(N)即可。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e6 + ;
ll a[maxn], b[maxn];
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
ll suma = , sumb = , ans;
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%lld%lld", &a[i], &b[i]), suma += a[i], sumb += b[i];
ans = min(suma, sumb);
for (int i = ; i <= n; i++)
ans = min(ans, suma - a[i] + sumb - b[i]);
printf("%lld\n", ans);
} }

最新文章

  1. 设计C/S架构应用程序的并发功能
  2. centos7.0 下安装jdk1.8
  3. WinCE下读取注册表获得SD路径
  4. java.lang包的分类
  5. HDU 4160
  6. 个性化推荐系统中的BadCase分析
  7. php自学笔记3
  8. Socket层实现系列 — send()类发送函数的实现
  9. Codeforces 629 E. Famil Door and Roads
  10. about unit test
  11. AOP 和 前置通知,后置通知
  12. PHP程序后台自动运行
  13. Java入门:基础算法之线性搜索
  14. CSS清除浮动常用方法小结
  15. Drupal学习(19) 使用jQuery
  16. 利用Docker安装Web前端性能测试工具Sitespeed.io
  17. TensorFlow学习笔记(五)图像数据处理
  18. 源码编译php
  19. Linux服务器上ftp的搭建和使用
  20. 如何把自己写的python程序给别人用

热门文章

  1. mybatis查询出字段为null,但是sql查出来有值
  2. LOJ#2330 榕树之心 树形dp
  3. C++ GUI Qt4学习笔记08
  4. 【JavaScript】包装类
  5. 【bzoj3463】[COCI2012] Inspector
  6. 支持向量机(一)----总述(点到平面的距离,Lagrange函数,Lagrange对偶)
  7. TCP服务器并发编程构架:完成端口IOCP模式
  8. BZOJ 3329: Xorequ(数位dp+递推)
  9. java 中创建线程有哪几种方式?
  10. Ta还没有分享呢,过段时间再来看看吧~ 解决办法