BZOJ

洛谷


对于每个人,每次枚举一个志愿看是否能增广即可。

对于第二问,可以保留第一问中\(n\)次增广前后的\(n\)张图,二分,在对应图上看是否能增广即可。

貌似匈牙利的某种写法比网络流优多了...懒得看...

写的常数莫名大...

增广失败的话原图流量不会变啊,不用特意删掉新加的边,把表头head改了即可,而且判断是否能增广只需要判断BFS()是否返回1。


Dinic:

//195228kb	6676ms
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=408,M=(N+40005)*2,INF=0x3f3f3f3f; int T;
struct Graph
{
int Enum,H[N],nxt[M],to[M],cap[M],cur[N],lev[N];
inline void Init(int n)
{
Enum=1, memset(H,0,n+1<<2);
}
inline void AE(int u,int v,int w)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0;
}
bool BFS()
{
static int q[N];
memset(lev,0,T+1<<2);
int h=0,t=1; q[0]=0, lev[0]=1;
while(h<t)
{
int x=q[h++];
for(int i=H[x]; i; i=nxt[i])
if(!lev[to[i]] && cap[i])
{
q[t++]=to[i], lev[to[i]]=lev[x]+1;
if(to[i]==T) return 1;
}
}
return 0;
}
int DFS(int x,int flow)
{
if(x==T) return flow;
int used=0;
for(int &i=cur[x]; i; i=nxt[i])
if(lev[to[i]]==lev[x]+1 && cap[i])
{
int delta=DFS(to[i],std::min(flow,cap[i]));
if(delta)
{
cap[i]-=delta, cap[i^1]+=delta, used+=delta;
if(used==flow) return flow;
}
}
return lev[x]=0,used;
}
void Dinic()
{
while(BFS()) memcpy(cur,H,T+1<<2), DFS(0,INF);
}
}G[203]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
} int main()
{
static int B[203],s[203],Ans1[203],tmpH[N];
static std::vector<int> v[203][203]; freopen("mentor.in","r",stdin);
freopen("mentor.out","w",stdout); for(int Tests=read(),C=read(); Tests--; )
{
int n=read(),m=read(); T=n+m+1;
G[0].Init(T);
for(int i=1; i<=n; ++i) G[0].AE(0,i,1);
for(int i=1; i<=m; ++i) G[0].AE(i+n,T,B[i]=read());
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j) v[i][j].clear();
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j) v[i][read()].push_back(j+n);
for(int i=1; i<=n; ++i) s[i]=read(); for(int i=1; i<=n; ++i)
{
G[i]=G[i-1];
int j;
for(j=1; j<=m; ++j)
{
std::vector<int> &vec=v[i][j];
for(int k=0,l=vec.size(); k<l; ++k) G[i].AE(i,vec[k],1);
if(G[i].BFS()) {G[i].Dinic(); break;}
if(vec.size()) G[i].Enum=G[i-1].Enum, memcpy(G[i].H,G[i-1].H,T+1<<2);
}
printf("%d ",Ans1[i]=j);
}
putchar('\n'); for(int i=1; i<=n; ++i)
if(Ans1[i]<=s[i]) putchar('0'), putchar(' ');
else
{
int l=1,r=i-1,mid,ans=0,dream=s[i];
while(l<=r)
{
mid=l+r>>1;
int tmpEnum=G[mid-1].Enum;
memcpy(tmpH,G[mid-1].H,T+1<<2);
bool ok=0;
for(int j=1; j<=dream; ++j)
{
std::vector<int> &vec=v[i][j];
for(int k=0,l=vec.size(); k<l; ++k) G[mid-1].AE(i,vec[k],1);
if(G[mid-1].BFS()) {ok=1; break;}
}
if(ok) ans=mid, l=mid+1;
else r=mid-1;
G[mid-1].Enum=tmpEnum, memcpy(G[mid-1].H,tmpH,T+1<<2);
}
printf("%d ",i-ans);
}
putchar('\n');
}
return 0;
}

ISAP:

//259320kb	7584ms
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=408,M=(N+40005)*2,INF=0x3f3f3f3f; int T;
struct Graph
{
int Enum,H[N],nxt[M],fr[M],to[M],cap[M],pre[N],lev[N];
inline void Init(int n)
{
Enum=1, memset(H,0,n+1<<2);
}
inline void AE(int u,int v,int w)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, fr[Enum]=u, cap[Enum]=w;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, fr[Enum]=v, cap[Enum]=0;
}
bool BFS()
{
static int q[N];
const int lim=T+1;
for(int i=0; i<T; ++i) lev[i]=lim;
int h=0,t=1; q[0]=T, lev[T]=0;
while(h<t)
{
int x=q[h++];
for(int i=H[x]; i; i=nxt[i])
if(cap[i^1] && lev[to[i]]==lim) q[t++]=to[i], lev[to[i]]=lev[x]+1;
}
return lev[0]<=T;
}
inline void Augment()
{
// int mn=INF;
// for(int i=T; i; i=fr[pre[i]])
// mn=std::min(mn,cap[pre[i]]);
for(int i=T; i; i=fr[pre[i]])
--cap[pre[i]], ++cap[pre[i]^1];
}
void ISAP()
{
static int cur[N],num[N];
memset(num,0,T+1<<2);
for(int i=0; i<=T; ++i) cur[i]=H[i], ++num[lev[i]];
int x=0;
while(lev[0]<=T)
{
if(x==T) x=0, Augment();
bool can=0;
for(int i=cur[x]; i; i=nxt[i])
if(lev[to[i]]==lev[x]-1 && cap[i])
{
can=1, cur[x]=i, pre[x=to[i]]=i;
break;
}
if(!can)
{
int mn=T;
for(int i=H[x]; i; i=nxt[i])
if(cap[i]) mn=std::min(mn,lev[to[i]]);
if(!--num[lev[x]]) break;
++num[lev[x]=mn+1], cur[x]=H[x];
if(x) x=fr[pre[x]];
}
}
}
}G[203]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
} int main()
{
static int B[203],s[203],Ans1[203],tmpH[N];
static std::vector<int> v[203][203]; freopen("mentor.in","r",stdin);
freopen("mentor.out","w",stdout); for(int Tests=read(),C=read(); Tests--; )
{
int n=read(),m=read(); T=n+m+1;
G[0].Init(T);
for(int i=1; i<=n; ++i) G[0].AE(0,i,1);
for(int i=1; i<=m; ++i) G[0].AE(i+n,T,B[i]=read());
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j) v[i][j].clear();
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j) v[i][read()].push_back(j+n);
for(int i=1; i<=n; ++i) s[i]=read(); for(int i=1; i<=n; ++i)
{
G[i]=G[i-1];
int j;
for(j=1; j<=m; ++j)
{
std::vector<int> &vec=v[i][j];
for(int k=0,l=vec.size(); k<l; ++k) G[i].AE(i,vec[k],1);
if(G[i].BFS()) {G[i].ISAP(); break;}
if(vec.size()) G[i].Enum=G[i-1].Enum, memcpy(G[i].H,G[i-1].H,T+1<<2);
}
printf("%d ",Ans1[i]=j);
}
putchar('\n'); for(int i=1; i<=n; ++i)
if(Ans1[i]<=s[i]) putchar('0'), putchar(' ');
else
{
int l=1,r=i-1,mid,ans=0,dream=s[i];
while(l<=r)
{
mid=l+r>>1;
int tmpEnum=G[mid-1].Enum;
memcpy(tmpH,G[mid-1].H,T+1<<2);
bool ok=0;
for(int j=1; j<=dream; ++j)
{
std::vector<int> &vec=v[i][j];
for(int k=0,l=vec.size(); k<l; ++k) G[mid-1].AE(i,vec[k],1);
if(G[mid-1].BFS()) {ok=1; break;}
}
if(ok) ans=mid, l=mid+1;
else r=mid-1;
G[mid-1].Enum=tmpEnum, memcpy(G[mid-1].H,tmpH,T+1<<2);
}
printf("%d ",i-ans);
}
putchar('\n');
}
return 0;
}

BZOJ.5251.[八省联考2018]劈配mentor(最大流)的更多相关文章

  1. [八省联考2018] 劈配 mentor

    Description 一年一度的综艺节目<中国新代码>又开始了.Zayid 从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. Input 轻车熟路的Zay ...

  2. BZOJ5251 八省联考2018劈配(网络流)

    劈配,匹配,网络流.那么考虑怎么跑网络流. 先看第一问.首先套路的建出超源超汇.不用想也知道导师向汇连容量为战队人数上限的边.特别地,给出局也建一个点,向汇连容量inf的边(似乎没有必要).对于一个新 ...

  3. 洛谷P4382 [八省联考2018]劈配(网络流,二分答案)

    洛谷题目传送门 说不定比官方sol里的某理论最优算法还优秀一点? 所以\(n,m\)说不定可以出到\(1000\)? 无所谓啦,反正是个得分题.Orz良心出题人,暴力有70分2333 思路分析 正解的 ...

  4. P4382 [八省联考2018]劈配

    题目链接 题意分析 受到了\(olinr\ \ julao\)的影响 写了匈牙利算法 首先 我们对于每一个人 从高到低枚举志愿 如果当前志愿的老师有剩余的话 那么我们就选 否则的话 我们看看谁的那个志 ...

  5. [BZOJ5251][九省联考2018]劈配(网络流)

    5251: [2018多省省队联测]劈配 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 33  Solved: 22[Submit][Status][ ...

  6. BZOJ5251:[九省联考2018]劈配——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5251 https://loj.ac/problem/2477  <-可以看数据 https: ...

  7. luogu P4382 [九省联考2018]劈配

    luogu 我记得我第一次做这道题的时候屁都不会qwq 先考虑第一问,暴力是依次枚举每个人,然后从高到低枚举志愿,枚举导师,能选就选.但是可以发现前面的人选的导师可能会导致后面的人本来可以选到这个志愿 ...

  8. 【BZOJ5251】【八省联考2018】劈配(网络流,二分答案)

    [BZOJ5251][八省联考2018]劈配(网络流,二分答案) 题面 洛谷 BZOJ Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序 ...

  9. [八省联考2018]林克卡特树lct——WQS二分

    [八省联考2018]林克卡特树lct 一看这种题就不是lct... 除了直径好拿分,别的都难做. 所以必须转化 突破口在于:连“0”边 对于k=0,我们求直径 k=1,对于(p,q)一定是从p出发,走 ...

随机推荐

  1. bzoj 1042

    典型的背包+容斥 首先,考虑如果没有个数的限制,那么就是一个完全背包,所以先跑一个完全背包,求出没有个数限制的方案数即可 接下来,如果有个数的限制,那么我们就要利用一些容斥的思想:没有1个超过限制的方 ...

  2. Java基础之多线程框架

    一.进程与线程的区别 1.定义: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比 ...

  3. easyui之自定义字体图标(鼠标覆盖时切换颜色)

    项目要求是自定义字体图标,使用easyui框架结构,众所周知easyui强功能弱样式,字体图标其实就是一张图片.要达到切换图标颜色的效果,要么就是有两套图,使用js控制.但是我这个人比较懒,不喜欢做复 ...

  4. springboot logback 相关使用

    参考: https://www.cnblogs.com/EasonJim/p/9159195.html https://blog.csdn.net/tianyaleixiaowu/article/de ...

  5. ReactNative调试技术-真机调试

    在我开始用ReactNative开始开发APP时,为了能够获取程序运行中的信息,就需要搭建调试环境. 手机调试方式有两类,一类是模拟器方式,另一类是真机模式. 我测试了一下相应的模拟器: 如果用谷歌管 ...

  6. 【Android】让Python在Android系统上飞一会儿

    第一节 在手机上配置Python运行环境 1.下载和安装 Scripting Layer for Android (SL4A) Scripting Layer for Android (SL4A) 是 ...

  7. 通过awk获取netstat命令中的进程号

    需要如下: 获取进程号

  8. Codeforces 316E3 线段树 + 斐波那切数列 (看题解)

    最关键的一点就是 f[ 0 ] * a[ 0 ] + f[ 1 ] * a[ 1 ] + ... + f[ n - 1] * a[ n  - 1] f[ 1 ] * a[ 0 ] + f[ 2 ] * ...

  9. Hive| ETL清洗& 查询练习

    ETL清洗数据 导Jar包 <dependencies> <dependency> <groupId>log4j</groupId> <artif ...

  10. 使用soupUI做接口测试

    第一步:点击“file”,选择测试项目采用的协议:(这里我们测试的是http协议的,所以选择第三项)   第二步:在弹窗中输入测试项目的接口URL,并点击“OK”: 第三步:设置和填写请求项的内容并点 ...