博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Prime Game Gym - 101981J(网络流/二分图)
阅读量:4700 次
发布时间:2019-06-09

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

网络流做法最要是建边

将m点分割限流
建立一个起点 连接2个点在于n相连 不过一个流量是inf 一个是k
再把n m连起来 跑最大流即可

二分图把 n m的边建2遍(注意开的n'是一个新的节点)

跑二分图的时候注意顺序,先跑原本的n的节点 再跑之后新建的n个节点
因为要保证优先不扩流(不用k)
但这样有可能会出现用别的边的流量的情况出现
所以在跑完二分图之后 判断一下原本的n个点可以用的最大流量
在 可用的最大流量+k 与 二分图结果 取min即可

网络流#include
using namespace std;#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3fconst int maxn=5e6+10;struct edge{ int u,v,w,next;}e[maxn*2];int n,m,k,maxflow,dep[maxn*2],tot=-1,g[maxn*2];void creatEdge(int u,int v,int w){ e[++tot]=(edge){u,v,w,g[u]}; g[u]=tot;}int bfs(int s,int t){ queue
q; mem(dep,-1); dep[s]=0; q.push(s); while(!q.empty()) { int now=q.front(); q.pop(); for(int i=g[now];i!=-1;i=e[i].next) { int v=e[i].v; if(dep[v]==-1&&e[i].w) { dep[v]=dep[now]+1; q.push(v); } } } return dep[t]==-1?0:1;}int dfs(int s,int t,int lim){ if(!lim||s==t) return lim; int flow=0,f; for(int i=g[s];i!=-1;i=e[i].next) { int v=e[i].v,w=e[i].w; if(dep[v]==dep[s]+1&&(f=dfs(v,t,min(lim,w)))) { flow+=f; lim-=f; e[i].w-=f; e[i^1].w+=f; if(!lim) break; } } return flow;}void Dinic(int s,int t){ int tot=0; while(bfs(s,t)) maxflow+=dfs(s,t,inf);}int main(){ int s,t; mem(g,-1); cin>>n>>m>>k; int tp=n+m; for(int i=1;i<=n;i++) { int tt; cin>>tt; for(int j=1;j<=tt;j++) { int v; cin>>v; creatEdge(2*m+i,v,1); creatEdge(v,2*m+i,0); } } int pos=4*500+1; for(int i=1;i<=m;i++) { creatEdge(i,i+m,1); creatEdge(i+m,i,0); creatEdge(i+m,pos+1,1); creatEdge(pos+1,i+m,0); } for(int i=1;i<=n;i++) { creatEdge(pos+2,2*m+i,1); creatEdge(2*m+i,pos+2,0); creatEdge(pos+3,2*m+i,1); creatEdge(2*m+i,pos+3,0); } creatEdge(pos+4,pos+3,500); creatEdge(pos+3,pos+4,0); creatEdge(pos+4,pos+2,k); creatEdge(pos+2,pos+4,0); s=pos+4,t=pos+1; Dinic(s,t);// cout<
<<" "<
<
二分图#include
using namespace std;const int maxn=6e5+10;struct node{ int u,v,next;}e[maxn];int n,m,k,temp;int g[maxn],vis[maxn],xM[maxn],yM[maxn],tot=0;int chk[maxn];void make(int u,int v){ e[++tot]={u,v,g[u]}; g[u]=tot;}int searchpath(int u){ for(int i=g[u];i;i=e[i].next) { int v=e[i].v; if(!chk[v]) { chk[v]=1; if(yM[v]==-1||searchpath(yM[v])) { yM[v]=u; xM[u]=v; return 1; } } } return 0;}int Maxmatch(){ int u,ret=0; memset(xM,-1,sizeof(xM)); memset(yM,-1,sizeof(yM)); for(u=m+1;u<=temp;u++) { if(xM[u]==-1) { memset(chk,0,sizeof(chk)); if(searchpath(u)) ret++; } } return ret;}int main(){ cin>>n>>m>>k; temp=m; for(int i=1;i<=n;i++) { int t; cin>>t; temp++; for(int j=1;j<=t;j++) { int now; cin>>now; make(temp,now); make(temp+n,now); } } temp+=n; int ans=Maxmatch(); int tt=0; for(int u=m+1;u<=m+n;u++) if(xM[u]!=-1) tt++; cout<
<

转载于:https://www.cnblogs.com/minun/p/11564775.html

你可能感兴趣的文章
【.NET】使用HtmlAgilityPack抓取网页数据
查看>>
工厂方法模式
查看>>
许愿墙的搭建基于mysql
查看>>
信息技术
查看>>
SQL中的内连接 外连接 左连接 右连接 全连接
查看>>
GitLab问题小结
查看>>
iOS-常用的辅助工具软件
查看>>
一道数学题
查看>>
虚函数 多层继承有重写 (3)
查看>>
[转]为什么大型网站前端使用 PHP 后台逻辑用 Java?
查看>>
php数组根据值获取键名
查看>>
[Swift]GZip字符串压缩和解压缩(Java/C#通用)
查看>>
[SwiftUI教程]4、处理用户输入
查看>>
[Swift]LeetCode106. 从中序与后序遍历序列构造二叉树 | Construct Binary Tree from Inorder and Postorder Traversal...
查看>>
[Xcode 实际操作]八、网络与多线程-(7)使用MessageUI框架,创建并发送一封带有附件的邮件...
查看>>
Repeater 无刷新分页
查看>>
Java学习不走弯路教程(9 三层结构)
查看>>
JS基础总结
查看>>
JVM 对象的创建、内存布局
查看>>
计算机的构成及工作原理等
查看>>