CODEVS1222 信与信封问题 (匈牙利算法)

先做一遍匈牙利算法。对于已经匹配的边,如果删去之后还能最大匹配数增加,则不符合要求。

一遍匈牙利算法是O(n^3)的,对于每一条边做n次,每次O(n^2),总的复杂度是O(n^3)。

注意:不要忘记输出none。

 1 var a:array[0..1000,0..1000] of boolean;
 2     l,r:array[0..1000] of longint;
 3     pd:array[0..1000] of boolean;
 4     i,j,x,y,n,sum,num:longint;
 5 function find(i:longint):boolean;
 6 var j:longint;
 7 begin
 8     for j:=1 to n do
 9         if a[i,j] and not pd[j] then
10         begin
11             pd[j]:=true;
12             if (l[j]=0) or find(l[j]) then
13             begin
14                 l[j]:=i;
15                 r[i]:=j;
16                 exit(true);
17             end;
18         end;
19     exit(false);
20 end;
21 begin
22     fillchar(a,sizeof(a),true);
23     readln(n);
24     readln(x,y);
25     while not ((x=0) and (y=0)) do
26     begin
27         a[x,y]:=false;
28         readln(x,y);
29     end;
30     fillchar(l,sizeof(l),0);
31     fillchar(r,sizeof(r),0);
32     sum:=0;
33     for i:=1 to n do
34     begin
35         fillchar(pd,sizeof(pd),false);
36         if find(i) then inc(sum);
37     end;
38     num:=0;
39     for i:=1 to n do
40     begin
41         fillchar(pd,sizeof(pd),false);
42                 j:=r[i];
43         a[i,j]:=false;
44         r[i]:=0; l[j]:=0;
45         if not find(i) then begin inc(num); writeln(i,‘ ‘,j); end;
46         a[i,j]:=true;
47         r[i]:=j; l[j]:=i;
48     end;
49     if num=0 then writeln(‘none‘);
50 end.
时间: 2024-12-18 05:37:25

CODEVS1222 信与信封问题 (匈牙利算法)的相关文章

codevs1222 信与信封问题

1222 信与信封问题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出.但是,第二天John的儿子Small John将这n封信都拿出了信封.不幸的是,Small John无法将拿出的信正确地装回信封中了. 将Small John所提供的n封信依次编号为1,2,…,n:且n个信封也依次编号为1,2,…,n.假定Small John能提供一组信息:第i封信肯

codevs1222 信与信封的问题

题目描述 Description John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出.但是,第二天John的儿子Small John将这n封信都拿出了信封.不幸的是,Small John无法将拿出的信正确地装回信封中了. 将Small John所提供的n封信依次编号为1,2,…,n:且n个信封也依次编号为1,2,…,n.假定Small John能提供一组信息:第i封信肯定不是装在信封j中.请编程帮助Small John,尽可能多地将信正确地装回信封. 输入描述 Input Des

WIKIOI 1222信与信封问题

题目描述 Description John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出.但是,第二天John的儿子Small John将这n封信都拿出了信封.不幸的是,Small John无法将拿出的信正确地装回信封中了. 将Small John所提供的n封信依次编号为1,2,…,n:且n个信封也依次编号为1,2,…,n.假定Small John能提供一组信息:第i封信肯定不是装在信封j中.请编程帮助Small John,尽可能多地将信正确地装回信封. 输入描述 Input Des

匈牙利算法

(一)首先明确匈牙利算法是干嘛滴? 匈牙利算法是解决二部图最大匹配问题滴. (二)算法的核心思想:不断寻找增广路径,每找到一条增广路径,就通过异或操作使匹配边数加一,直到找不到增广路径,算法结束. (三)算法的基本步骤: (1)任取二部图G(X,Y)的匹配M,若M饱和X,则停止.若M不能饱和X,则取X的未标记的M非饱和点x.(标记的点表示经过此点不存在增广路)令S={x},T= ?.(T集合中的点表示N(S)中已经加入增广路的点)(当不存非饱和点或者所有非饱和点都被标记,算法结束) (2)若N(

匈牙利算法dfs模板 [二分图][二分图最大匹配]

最近学了二分图最大匹配,bfs模板却死活打不出来?我可能学了假的bfs 于是用到了dfs模板 寻找二分图最大匹配的算法是匈牙利算法 匈牙利算法的主要程序是寻找增广路 寻找增光路是过程是:从一个未经配对的点出发,历经未配边.匹配边.未配边.匹配边.未配边....最终到达一个未配点的过程,只要把路径中的未配边和匹配边的“身份”对调,匹配就加一了.这就是一个寻找增广路的过程,通过不断寻找增广路,可以找到最大的匹配. 1 #include<cstdio> 2 #include<cstring&g

【codevs】1022覆盖(匈牙利算法)

嗯,先上题目描述... 此题接近裸的匈牙利算法,将陆地和其四周是陆地的点连一条边,这样就有了一个无向图. 接着就是从第一个点出发枚举未被标记的点,标记与其对应的另一个点(因为是1*2的长方形). 开了一个四维数组e[x1][y1][x2][y2],若为零代表点(x1,y1)与(x2,y2)不连通. match[x1][y1][1]放与点(x1,y1)配对的另一个点的x,match[x1][y1][2]放与点(x1,y1)配对点的y. 还有就是更改的时候记得双向更改,因为是无向图啊. 然后就跑df

FOJ 2232 匈牙利算法找二分图最大匹配

题目链接 简单理解匈牙利算法 简单理解二分图 尽量让每一个随从击败一个对手且随从全部存活,关键是为每一个随从找对手(递归过程),"腾". #include<iostream> #include<cstdio> #include<cstring> using namespace std; int used[110]; int g[110][110]; //建立随从和对手的对战关系 int ee[110]; int n; struct people{ i

匈牙利算法——S.B.S.

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法. -------等等,看得头大?那么请看下面的版本: 通过数代人的努力,你终于赶上了剩男剩女的大潮,假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每个人都可能对多名异性有好感(-_-||暂时不考虑特殊的性取向),如果一对男女互有好感,那么你就可以把这一对撮合在一起,现在

UVALive5874 - Social Holidaying-二分图匹配/匈牙利算法

有n个家庭,m个房间,一个房间只能两个家庭住.求最大匹配. 比较标准的二分图问题.先初始化把可能的家庭建边,然后跑一边匈牙利算法. 最后的答案是最大匹配数/2,因为建图时有重复. #include <cstdio> #include <algorithm> #include <cstring> #include <map> using namespace std; const int MAXN = 410; int uN,vN; int g[MAXN][MA