二分图最大匹配模板(pascal)

uoj#78. 二分图最大匹配

从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生。编号分别为 1,…,nl1,…,nl 和 1,…,nr1,…,nr。

有若干个这样的条件:第 vv 个男生和第 uu 个女生愿意结为配偶。

请问这个班级里最多产生多少对配偶?

输入格式

第一行三个正整数,nl,nr,mnl,nr,m。

接下来 mm 行,每行两个整数 v,uv,u 表示第 vv 个男生和第 uu 个女生愿意结为配偶。保证 1≤v≤nl1≤v≤nl,1≤u≤nr1≤u≤nr,保证同一个条件不会出现两次。

输出格式

第一行一个整数,表示最多产生多少对配偶。

接下来一行 nlnl 个整数,描述一组最优方案。第 vv 个整数表示 vv 号男生的配偶的编号。如果 vv 号男生没配偶请输出 00。

样例一

input

2 2 3
1 1
1 2
2 1

output

2
2 1

explanation

11 号男生跟 22 号女生幸福地生活在了一起~

22 号男生跟 11 号女生幸福地生活在了一起~

样例二

input

2 2 2
1 1
2 1

output

1
1 0

explanation

班上一个女神一个女汉子,两个男生都去追女神。一种最优方案是:

11 号男生跟 11 号女生幸福地生活在了一起~

22 号男生孤独终生。= =||

限制与约定

1≤nl,nr≤5001≤nl,nr≤500,1≤m≤2500001≤m≤250000。

时间限制:1s

空间限制:256MB

打个板子玩玩,不料还WA了一次。原因是把队列数组也开成-550~550了。

 1 program rrr(input,output);
 2 const
 3   inf=123456789;
 4 type
 5   etype=record
 6      t,c,next,rev:longint;
 7   end;
 8 var
 9   e:array[0..600000]of etype;
10   a,cur,d:array[-550..550]of longint;
11   q:array[0..1100]of longint;
12   l,r,i,x,y,j,m,cnt,ans,h,t:longint;
13 function min(a,b:longint):longint;
14 begin
15    if a<b then exit(a) else exit(b);
16 end;
17 procedure ins(x,y,c:longint);
18 begin
19    inc(cnt);e[cnt].t:=y;e[cnt].c:=c;e[cnt].next:=a[x];a[x]:=cnt;
20 end;
21 procedure add(x,y,c:longint);
22 begin
23    ins(x,y,c);e[cnt].rev:=cnt+1;ins(y,x,0);e[cnt].rev:=cnt-1;
24 end;
25 procedure bfs;
26 begin
27    for i:=-l to r+1 do d[i]:=-1;d[0]:=0;
28    h:=0;t:=1;q[1]:=0;
29    while h<t do
30       begin
31          inc(h);
32          i:=a[q[h]];
33          while i<>0 do
34             begin
35                if (d[e[i].t]=-1) and (e[i].c>0) then
36                   begin
37                      d[e[i].t]:=d[q[h]]+1;
38                      inc(t);q[t]:=e[i].t;
39                   end;
40                i:=e[i].next;
41             end;
42       end;
43 end;
44 function dfs(k,f:longint):longint;
45 var
46   ans,t,i:longint;
47 begin
48    if (k=r+1) or (f=0) then exit(f);
49    ans:=0;i:=cur[k];
50    while i<>0 do
51       begin
52          if (d[e[i].t]=d[k]+1) and (e[i].c>0) then
53             begin
54                t:=dfs(e[i].t,min(f,e[i].c));
55                dec(e[i].c,t);inc(e[e[i].rev].c,t);
56                inc(ans,t);dec(f,t);
57                if f=0 then break;
58             end;
59          i:=e[i].next;cur[k]:=i;
60       end;
61    if f>0 then d[k]:=-1;
62    exit(ans);
63 end;
64 begin
65    assign(input,‘r.in‘);assign(output,‘r.out‘);reset(input);rewrite(output);
66    readln(l,r,m);
67    fillchar(a,sizeof(a),0);cnt:=0;
68    for i:=1 to l do add(0,-i,1);
69    for i:=1 to m do begin readln(x,y);add(-x,y,1); end;
70    for i:=1 to r do add(i,r+1,1);
71    ans:=0;
72    while true do
73       begin
74          bfs;
75          if d[r+1]=-1 then break;
76          for i:=-l to r+1 do cur[i]:=a[i];
77          ans:=ans+dfs(0,inf);
78       end;
79    writeln(ans);
80    for i:=1 to l do
81       begin
82          j:=a[-i];
83          while j<>0 do begin if e[j].c=0 then break;j:=e[j].next; end;
84          if j=0 then write(0,‘ ‘) else write(e[j].t,‘ ‘);
85       end;
86    close(input);close(output);
87 end.
时间: 2024-12-19 01:32:24

二分图最大匹配模板(pascal)的相关文章

二分图最大匹配模板【匈牙利;Dinic最大流】

二分图最大匹配模板[匈牙利:Dinic最大流] 匈牙利算法 int n,m; vector<int> map[100010]; int match[100010];//保存匹配的互相点 bool vis[100010]; bool dfs(int u) { for(int j=0;j<map[u].size();j++) { int v=map[u][j]; if(!vis[v]) { vis[v]=true; if(!match[v]||dfs(match[v])) { match[v

二分图最大匹配模板

/**************************************************** 二分图匹配(匈牙利算法的DFS实现) INIT:g[][]两边定点划分的情况 CALL:res=hungary();输出最大匹配数 优点:适于稠密图,DFS找增广路快,实现简洁易于理解 时间复杂度:O(VE); ****************************************************/ const int MAXN=1000; int uN,vN; //u,

HDU - 1083 Courses (二分图最大匹配模板)

题意:给出P门课程,N个学生.每一门课程可能有多个学生感兴趣然后我们需要匹配,使得每一门课程都只包含一名对其感兴趣的学生问:能否匹配成立思路:这个就是典型的二分图匹配问题.常用匈牙利算法 完整代码:(一开始写成了无向图....)写成有向图是因为学生是可以剩余的 #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; c

二分图——多重匹配模板hdu1669

好像多重匹配一般是用网络流来做的.. 这是匈牙利算法的模板:lim是每个组的上界 思路是每个组都可以匹配lim个点,那么当点x遇到的组匹配的点数还没有超过lim时,直接匹配即可 如果已经等于了lim,这时就要从这个组的lim个点里找到一个能匹配到其他组的点(类似于普通匹配的寻找增广路过程) int dfs(int x,int lim){ for(int i=1;i<=m;i++)//枚举每个组 if(!vis[i] && mp[x][i]){ vis[i]=1; if(match[i

二分图最大匹配基本模板

最小顶点覆盖==二分图的最大匹配最少路径覆盖==n—最大匹配////n为左右集合中的顶点个数最大点独立集 = 顶点共个数 - 匹配顶点数 多个环的并?    例如:有n个国家,国家之间通过有向边相连,边有权值,?    现在让你把所有的国家都划成一个一个的圈,使得所有圈的总权值和最大.?    二分图的实质就是多个环,该题就是直接求出的二分图的最大权匹配就能求出最终结果.?    二分图的多个环的并就是二分图的最大(小)权匹配.?    所以KM求得最大匹配就是结果////////下面给出关于二

【二分图匹配入门专题1】H - Marriage Media light oj 1184【二分图最大匹配】

You run a marriage media. You take some profiles for men and women, and your task is to arrange as much marriages as you can. But after reading their bio-data you have found the following criteria. No man will marry a woman if their height gap is gre

【HDOJ 2063】过山车

[HDOJ 2063]过山车 二分图最大匹配模板题 1女对n男 问匹配最大对数 代码如下: #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #define INF 0x3f3f3f3f using namespace std; vector <int> head[555]; bool vis[555

二分图最优匹配模板

const int MAX = 1e6+10;const int inf = 0x3f3f3f3f;int n,m;int lx[MAX],ly[MAX];int match[MAX];int usex[MAX],usey[MAX];int w[MAX][MAX];int find(int u) {    usex[u]=1;    for(int i=0;i<m;i++) {        if(!usey[i]&&w[u][i]==ly[i]+lx[u]) {          

XidianOJ 1048 二分图匹配模板

题目描述 西电ACM实验室是一个很和谐的实验室,有n个男生和m个女生组成(m>0),尽管表面大家都全心全意地为了荣誉而战,然而经过亮亮的深入调查,我们已经知道了有一些人三心二意:每天只有99%的时间花费在切题上,而还有1%的时间在想着某位或某几位异性!作为FFF团西电分部的部长,亮亮显然不能容许这种朝三暮四的情况.但是西电ACM实验室又是一个很开明的实验室,于是亮亮决定尽可能的撮合实验室的队员! 那么问题来了,亮亮最多能撮合多少对呢? 输入 多组数据,每组数据首先是两个整数,n,m表示男女生的人