Hung nha lợi toán phápThị nhất chủng tạiĐa hạng thức thời gianNội cầu giảiNhậm vụ phân phối vấn đềĐíchTổ hợp ưu hóaToán pháp,Tịnh thôi động liễu hậu lai đíchNguyên thủy đối ngẫu phương pháp.1955 niên, khố ân (W.W.Kuhn) lợi dụng hung nha lợi sổ học gia khang ni cách (D.Kőnig) đích nhất cá định lý cấu tạo liễu giá cá giải pháp, cố xưng vi hung nha lợi pháp.[2]
- Trung văn danh
- Hung nha lợi toán pháp
- Ngoại văn danh
- Hungary
- Đề xuất giả
- W.W.Kuhn[2]
- Đề xuất thời gian
- 1955 niên
- Toán pháp đích hạch tâm
- Tầm trảoTăng quảng lộKính
Thiết Thị nhất cá vô hướng đồ. Như đỉnh điểm tập V khả phân cát vi lưỡng cá hỗ bất tương giao đích tử tập ,Tuyển trạch giá dạng đích tử tập trung biên sổ tối đại đích tử tập xưng vi đồ đích tối đạiThất phốiVấn đề ( maximal matching problem ).
Như quả nhất cá thất phối trung, Thả thất phối sổ ,Tắc xưng thử thất phối vi hoàn toàn thất phối, dã xưng tác hoàn bị thất phối. Đặc biệt đích đương Xưng vi hoàn mỹ thất phối.[1]
Tại giới thiệu hung nha lợi toán pháp chi tiền hoàn thị tiên đề nhất hạ kỉ cá khái niệm, hạ diện M thị G đích nhất cá thất phối.
Nhược , ,Kỳ trung biên Dĩ kinh tại thất phối M thượng.
M- giao thác lộ: p thị G đích nhất điều thông lộ, như quả p trung đích biên vi chúc vu M trung đích biên dữ bất chúc vu M đãn chúc vu G trung đích biên giao thế xuất hiện, tắc xưng p thị nhất điều M- giao thác lộ. Như: Lộ kính , .
M- bão hòa điểm: Đối vu ,Như quả v dữ M trung đích mỗ điều biên quan liên, tắc xưng v thị M- bão hòa điểm, phủ tắc xưng v thị phi M- bão hòa điểm. Như Đô chúc vu M- bão hòa điểm, nhi kỳ tha điểm đô chúc vu phi M- bão hòa điểm.
M- khảTăng quảng lộ:p thị nhất điều M- giao thác lộ, như quả p đích khởi điểm hòa chung điểm đô thị phi M- bão hòa điểm, tắc xưng p vi M- khả tăng quảng lộ. Như ( bất yếu hòa lưu võng lạc trung đích tăng quảng lộ kính lộng hỗn liễu ).
Cầu tối đạiThất phốiĐích nhất chủng hiển nhi dịch kiến đích toán pháp thị: Tiên trảo xuất toàn bộ thất phối, nhiên hậu bảo lưu thất phối sổ tối đa đích. Đãn thị giá cá toán pháp đíchThời gian phục tạp độVi biên sổ đích chỉ sổ cấp hàm sổ. Nhân thử, nhu yếu tầm cầu nhất chủng canh gia cao hiệu đích toán pháp. Hạ diện giới thiệu dụng tăng quảng lộ cầu tối đại thất phối đích phương pháp ( xưng tác hung nha lợi toán pháp,Hung nha lợiSổ học giaEdmondsVu 1965 niên đề xuất ).
Tăng quảng lộĐích định nghĩa ( dã xưng tăng quảng quỹ hoặc giao thác quỹ ):
Nhược P thị đồ G trung nhất điều liên thông lưỡng cá vị thất phối đỉnh điểm đích lộ kính, tịnh thả chúc vu M đích biên hòa bất chúc vu M đích biên ( tức dĩ thất phối hòa đãi thất phối đích biên ) tại P thượng giao thế xuất hiện, tắc xưng P vi tương đối vu M đích nhất điều tăng quảng lộ kính.
Do tăng quảng lộ đích định nghĩa khả dĩ thôi xuất hạ thuật tam cá kết luận:
( 1 ) P đích lộ kính cá sổ tất định vi kỳ sổ, đệ nhất điều biên hòa tối hậu nhất điều biên đô bất chúc vu M.
( 2 ) tương M hòa P tiến hành thủ phản thao tác khả dĩ đắc đáo nhất cá canh đại đích thất phối .
( 3 ) M vi G đích tối đại thất phối đương thả cận đương bất tồn tại M đích tăng quảng lộ kính.
Toán pháp luân khuếch:
( 1 ) trí M vi không
( 2 ) trảo xuất nhất điều tăng quảng lộ kính P, thông quá dị hoặc thao tác hoạch đắc canh đại đích thất phối Đại thế M
Không gian phục tạp độ lân tiếp củ trận: Lân tiếp biểu:
Cách thức thuyết minh
Thâu nhập cách thức:
Đệ 1 hành 3 cá chỉnh sổ, Đích tiết điểm sổ mục ,G đích biên sổ m[1]
Đệ 2-m+1 hành, mỗi hành lưỡng cá chỉnh sổ ,Đại biểu Trung biên hào vi Đích điểm hòa Trung biên hào vi Đích điểm chi gian hữu biên tương liên
Thâu xuất cách thức:
Lân tiếp củ trận -C
#include<stdio.h>
#include<string.h>
int n1, n2, m, ans;
int result[101];// ký lục V2 trung đích điểm thất phối đích điểm đích biên hào
bool state[101];// ký lục V2 trung đích mỗi cá điểm thị phủ bị sưu tác quá
bool data[101][101];// lân tiếp củ trận true đại biểu hữu biên tương liên
void init()
{
int t1, t2;
memset(data, 0, sizeof(data));
memset(result, 0, sizeof(result));
ans = 0;
scanf( "%d%d%d", &n1, &n2, &m);
for(int i = 1; i <= m; i++)
{
scanf( "%d%d", &t1, &t2);
data[t1][t2] = true;
}
return;
}
bool find(inta)
{
for(int i = 1; i <= n2; i++)
{
if(data[a][i] == 1 &&!state[i]) // như quả tiết điểm i dữ a tương lân tịnh thả vị bị tra trảo quá
{
state[i] = true; // tiêu ký i vi dĩ tra trảo quá
if(result[i] == 0 // như quả i vị tại tiền nhất cá thất phối M trung
|| find(result[i])) //i tại thất phối M trung, đãn thị tòng dữ i tương lân đích tiết điểm xuất phát khả dĩ hữu tăng quảng lộ
{
result[i] = a; // ký lục tra trảo thành công ký lục
return true;// phản hồi tra trảo thành công
}
}
}
return false;
}
int main()
{
init();
for(int i = 1; i <= n1; i++)
{
memset(state, 0, sizeof(state)); // thanh không thượng thứ sưu tác thời đích tiêu ký
if(find(i))
{
ans++; // tòng tiết điểm i thường thí khoách triển
}
}
printf( "%d\n", ans);
return 0;
}
Lân tiếp củ trận -pascal
Programhungary;
Const
max=100;
Var
data:array[1..max,1..max]ofboolean;{ lân tiếp củ trận }
result:array[1..max]ofinteger;{ ký lục đương tiền liên tiếp phương thức }
state:array[1..max]ofboolean;{ ký lục thị phủ biến lịch quá, phòng chỉ tử tuần hoàn }
m,n1,n2,i,t1,t2,ans:integer;
Function dfs(p:integer):boolean;
var
i:integer;
begin
for i:=1 to n2 do
if data[p,i]and not(state[i]) then{ hữu biên tồn tại thả một hữu bị sưu tác quá }
begin
state[i]:=true;
if (result[i]=0)or dfs(result[i]) then{ một hữu bị liên quá hoặc tầm trảo đáo tăng quảng lộ }
begin
result[i]:=p;
exit(true);
end;
end;
exit(false);
end;
begin
readln(n1,n2,m);
fillchar(data,sizeof(data),0);
fori:=1 to mdo
begin
readln(t1,t2 );
data[t1,t2]:=true;
end;
fillchar(result,sizeof(result),0);
ans:=0;
fori:=1 to n1 do
begin
fillchar(state,sizeof(state),0);
if dfs(i) then inc(ans);
end;
writeln(ans);
end.
Lân tiếp biểu -pascal ( sử dụng động thái liên biểu )
( phương pháp cơ vu chi tiền đích lân tiếp củ trận -pascal )
programhungarian_algorithm;// hung nha lợi toán pháp
type
node=^link;// liên biểu định nghĩa
link=record
g:longint;// chỉ hướng tiết điểm
next:node;
end;
var
n1,n2,m,a,v1,v2,ans:longint;
flag:array[1..1000000]ofboolean;// ký lục tại main đệ quy quá trình trung thị phủ dĩ phóng vấn quá, phòng chỉ tử tuần hoàn
nd:array[1..1000000]ofnode;// lân tiếp biểu
resultt:array[1..1000000]oflongint;// ký lục v2 trung tiết điểm đích tối chung thất phối vu v1 trung đích kỉ hào tiết điểm
functionmain(wei:longint):boolean;
varp:node;
begin
p:=nd[wei];
whilep<>nildo
begin
ifflag[p^.g]{ một hữu bị sưu tác quá }
thenbegin
flag[p^.g]:=false;
if(resultt[p^.g]=0)or(main(resultt[p^.g])){ một hữu bị liên quá hoặc nguyên lai chỉ hướng đích tiết điểm tầm trảo đáo tân đích tăng quảng lộ }
thenbegin
resultt[p^.g]:=wei;
exit(true);
end;
end;
p:=p^.next;
end;
exit(false)
end;
procedureaddd(v1,v2:longint);// kiến lập lân tiếp biểu quá trình
varp:node;
begin
new(p);
p^.g:=v2;
p^.next:=nd[v1];
nd[v1]:=p;
end;
begin
readln(n1,n2,m);
fora:=1tomdo
begin
readln(v1,v2);
addd(v1,v2);
end;
ans:=0;
fillchar(resultt,sizeof(resultt),0);
fora:=1ton1do
begin
fillchar(flag,sizeof(flag),true);
ifmain(a)
theninc(ans);
end;
writeln(ans);
fora:=1ton2do
ifresultt[a]<>0
thenwriteln(resultt[a],'---',a);
end.
Lân tiếp biểu -C++
#include<iostream>
#include<cstring>
using namespace std;
// định nghĩa liên biểu
struct link{
int data;// tồn phóng sổ cư
link*next;// chỉ hướng hạ nhất cá tiết điểm
link(int=0);
};
link::link(int n){
data=n;
next=NULL;
}
int n1,n2,m,ans=0;
int result[101];// ký lục n1 trung đích điểm thất phối đích điểm đích biên hào
bool state[101];// ký lục n1 trung đích mỗi cá điểm thị phủ bị sưu tác quá
link*head[101];// ký lục n2 trung đích điểm đích lân tiếp tiết điểm
link*last[101];// lân tiếp biểu đích chung chỉ vị trí ký lục
// phán đoạn năng phủ trảo đáo tòng tiết điểm n khai thủy đích tăng quảng lộ
bool find(const int n){
link*t=head[n];
while(t!=NULL){//n nhưng hữu vị tra trảo đích lân tiếp tiết điểm thời
if(!(state[t->data])){// như quả lân tiếp điểm t->data vị bị tra trảo quá
state[t->data]=true;// tiêu ký t->data vi dĩ kinh bị trảo quá
if((result[t->data]==0)||// như quả t->data bất chúc vu tiền nhất cá thất phối M
(find(result[t->data]))){// như quả t->data thất phối đáo đích tiết điểm khả dĩ tầm trảo đáo tăng quảng lộ
result[t->data]=n;// na ma khả dĩ canh tân thất phối M', kỳ trung n1 trung đích điểm t->data thất phối n
return true;// phản hồi thất phối thành công đích tiêu chí
}
}
t=t->next;// kế tục tra trảo hạ nhất cá n đích lân tiếp tiết điểm
}
return false;
}
int main(){
int t1=0,t2=0;
cin>>n1>>n2>>m;
for(int i=0;i<m;i++){
cin>>t1>>t2;
if(last[t1]==NULL)
last[t1]=head[t1]=new link(t2);
else
last[t1]=last[t1]->next=new link(t2 );
}
for(int i=1;i<=n1;i++){
memset(state,0,sizeof(state));
if(find(i))ans++;
}
cout<<ans<<endl;
return 0;
}
Lân tiếp củ trận -C++
#include<iostream>
#include<cstring>
using namespace std;
int map[105][105];
int visit[105],flag[105];
int n,m;
bool dfs(int a)
{
for(int i=1; i<=n; i++)
{
if(map[a][i]&&!visit[i])
{
visit[i]=1;
if(flag[i]==0||dfs(flag[i]))
{
flag[i]=a;
return true;
}
}
}
return false;
}
int main()
{
int n1,n2;
while(cin>>n1 >>n2 >>m)
{
n=n1;
memset(map,0,sizeof(map));
for(int i=1; i<=m; i++)
{
int x,y;
cin>>x>>y;
map[x][y]=1;
}
memset(flag,0,sizeof(flag));
int result=0;
for(int i=1; i<=n1; i++)
{
memset(visit,0,sizeof(visit));
if(dfs(i))result++;
}
cout<<result<<endl;
}
return 0;
}