学了网络流这么久了,今天才知道霍尔定理。
转载自
https://v.qq.com/x/page/d0543uhskl8.html
和
https://www.cnblogs.com/isakovsky/p/11355201.html
霍尔定理
作用:霍尔定理定理用来判断二分图是否满足完全匹配的充要条件
要求:
- |X| = |Y| (两边点数相等
- 对于X的任意子集w,满足 |w| <= |Ng(w)|
性质:
S的最大匹配:|S|-max(|w|-|Ng(w)|) (w为S的任意子集
本题里,要取得max(|w|-|Ng(w)|),可以通过枚举 |w| 得到,
- |w|=0, Ng(w)=0
- |w|=一个班的学生,Ng(w)=其他班的奶茶之和
- 否则|w|=多个班的学生之和,Ng(w)=所有奶茶
第一种情况直接为初始值
第二种情况 直接枚举第i个班
在第三种情况中,很明显直接取所有的班级的学生作为w时,|w|-|Ng(w)| 最大
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
typedef long long LL;
const int N=1e6+5;
int n,m;
int a[N],b[N];
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
LL ans=0;
LL sum1=0,sum2=0;
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
sum1+=a[i];
sum2+=b[i];
}
//我的目的是得到max(|w|-|Ng(w)|),显然w=0时,就是第一种情况
//第一种情况
ans=0;
//第二种情况
for(int i=1;i<=n;i++)
ans=max(ans,a[i]-(sum2-b[i]));//w-Ng(w)
//第三种情况
ans=max(ans,sum1-sum2);
printf("%lld\n",sum1-ans);
}
return 0;
}