探讨网络流量中的二分图配对方法
最编程
2024-07-25 22:13:01
...
Luogu P3386
首先看看二分图的定义:
二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。——百度百科
举个例子:这样的一个图就是二分图。
那么什么叫做二分图的匹配?
也就是在二分图中选择若干条边,其中任意两条边的端点不相同。此时边集元素的个数就是二分图的一个匹配。
那么很显然二分图的最大匹配就是边集个数最多的情况。
举个例子:
下面图中红色边构成了一个二分图匹配
下面图中红色边不构成二分图匹配
对于二分图最大匹配的问题,我们通常匈牙利算法或者网络最大流来解决。我完全没有学过匈牙利算法,所以 本文着重于网络最大流。不过其实没什么好分析的
如图所示:对二分图建立一个超级源点和一个超级汇点,源点向点集\(A\)连一条容量为\(1\)的边,点集\(B\)x向汇点连一条容量为\(1\)的边,然后跑一遍最大流即可。
由于在二分图中\(Dinic\)算法的效率非常高,甚至高于匈牙利算法,所以我们通常使用\(Dinic\)跑二分图匹配
#include<cstdio>
#include<queue>
using namespace std;
int n,m,num,cnt,u,v,head[2005],cur[2005],dis[2005],ans;
bool vis[2005];
struct data
{
int to,next,val;
}e[5000005];
void add(int u,int v,int val)
{
e[++cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
e[cnt].val=val;
}
bool bfs(int s,int t)
{
queue<int> que;
que.push(s);
for (int i=1;i<=n+m+2;i++) dis[i]=0,vis[i]=false,cur[i]=head[i];
vis[s]=true;
dis[s]=1;
while (!que.empty())
{
int now=que.front();
que.pop();
for (int i=head[now];i;i=e[i].next)
{
v=e[i].to;
if (!vis[v]&&e[i].val>0)
{
dis[v]=dis[now]+1;
vis[v]=true;
if (v==t) return true;
que.push(v);
}
}
}
return false;
}
int dfs(int now,int t,int flow)
{
if (!flow||now==t) return flow;
int used=0;
for (int i=cur[now];i;i=e[i].next)
{
cur[now]=i;
v=e[i].to;
if (dis[now]+1!=dis[v]) continue;
int tmp=dfs(v,t,min(flow-used,e[i].val));
if (tmp)
{
e[i].val-=tmp;
e[i^1].val+=tmp;
used+=tmp;
if (flow-used==0) return flow;
}
}
return used;
}
void Dinic(int s,int t)
{
while (bfs(s,t)) ans+=dfs(s,t,0x7fffffff);
}
int main()
{
scanf("%d%d%d",&n,&m,&num);
cnt=1;
for (int i=1;i<=num;i++)
{
scanf("%d%d",&u,&v);
if (u>n||v>m) continue;
add(u,v+n,1);
add(v+n,u,0);
}
for (int i=1;i<=n;i++) add(n+m+1,i,1),add(i,n+m+1,0);
for (int i=n+1;i<=m+n;i++) add(i,n+m+2,1),add(n+m+2,i,0);
Dinic(n+m+1,n+m+2);
printf("%d",ans);
return 0;
}
推荐阅读
-
理解工作流:自动化业务流程管理与Activiti实践" **简述** 工作流(Workflow)是一种利用电脑技术自动化管理业务流程的方式,让不同参与者按既定路径执行任务,确保文档、信息或任务在预设规则下顺利传递,最终达成期望的业务目标。 **核心概念** - **工作流自动化**: 计算机驱动业务流程处理与执行,如在参与者间自动传递文档和任务。 - **目标与应用**: 管理工作流程确保按时、由合适的人执行,同时允许人工介入以增强灵活性。 - **工作流框架示例**: Activiti、JBPM、OSWorkflow 和 Workflow,它们背后通常依赖数据库支持。 - **关键组件**: ProcessEngine 在 Activiti 中扮演核心角色,负责流程实例创建、数据管理和流程监控。 **相关领域** - **业务流程管理 (BPM)**: 一种系统性方法论,聚焦于构建并优化端到端卓越业务流程以提升企业业绩,在EMBA、MBA等商业课程中得到关注。 - **业务流程建模与标记语言 (BPMN)**: 用于绘制业务流程图的工具,探讨其在不同场景下的应用精确度、标准化价值以及未来发展愿景。 **辅助术语** - 流对象 (Flow Objects): BPMN 中用于描述流程中活动、决策、序列和其他元素的具体实现单元。
-
探讨网络流量中的二分图配对方法