匈牙利算法与KM算法

匈牙利算法

 1 var
 2   i,j,k,l,n,m,mm,ans:longint;
 3   a:array[0..501,0..501]of longint;
 4   p,f:array[0..501]of longint;
 5 function xyl(x,y:longint):boolean;
 6 var i,j,k,l:longint;
 7 begin
 8   if f[x]=y then exit(false);
 9   f[x]:=y;
10   for i:=1 to m do
11   if(a[x,i]=1)and((p[i]=0)or(xyl(p[i],y)))then
12   begin p[i]:=x; exit(true); end;
13   exit(false);
14 end;
15 begin
16   readln(n,m,mm);
17   for i:=1 to mm do
18   begin
19     readln(j,k);
20     a[j,k]:=1;
21   end;
22   for i:=1 to n do if xyl(i,i) then inc(ans);
23   writeln(ans);
24 end.
Pascal
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[502][502],p[502],f[502],n,m,mm,j,k,ans;
 4 bool xyl(int x,int y)
 5 {
 6     if(f[x]==y)return 0; f[x]=y;
 7     for(int i=1;i<=m;i++)if((a[x][i]==1)and((p[i]==0)or(xyl(p[i],y)))){p[i]=x; return 1;}
 8     return 0;
 9 }
10 int main()
11 {
12     scanf("%d%d%d",&n,&m,&mm);
13     for(int i=1;i<=mm;i++){scanf("%d%d",&j,&k); a[j][k]=1;}
14     for(int i=1;i<=n;i++)if(xyl(i,i))ans++;
15     printf("%d",ans);
16 }
C++

 

KM算法

 1 uses math;
 2 var
 3   ii,i,j,k,l,n,m,v,mm,down:longint;
 4   a:array[0..501,0..501]of longint;
 5   p,v1,v2,d1,d2,s:array[0..501]of longint;
 6   ans:int64;
 7 function km(x:longint):boolean;
 8 var i,j,k,l:longint;
 9 begin
10   v1[x]:=1;
11   for i:=1 to m do
12   if(v2[i]=0)and(d1[x]+d2[i]=a[x,i])then
13   begin
14     v2[i]:=1;
15     if(p[i]=0)or(km(p[i]))then
16     begin p[i]:=x; exit(true); end;
17   end else
18   begin
19     if v2[i]=0 then s[i]:=min(s[i],d2[i]+d1[x]-a[x,i]);
20   end;
21   exit(false);
22 end;
23 begin
24   readln(n,m,mm);
25   for i:=1 to mm do
26   begin
27     readln(j,k,l);
28     a[j,k]:=max(a[j,k],l);
29     d1[j]:=max(d1[j],a[j,k]);
30   end;
31   if m<n then m:=n;
32   for ii:=1 to n do
33   begin
34     while true do
35     begin
36       for i:=1 to n do v1[i]:=0;
37       for i:=1 to m do begin v2[i]:=0; s[i]:=maxlongint; end;
38       if km(ii) then break;
39       down:=maxlongint;
40       for i:=1 to m do if v2[i]=0 then down:=min(s[i],down);
41       for i:=1 to n do if v1[i]=1 then d1[i]:=d1[i]-down;
42       for i:=1 to m do if v2[i]=1 then d2[i]:=d2[i]+down;
43     end;
44   end;
45   for i:=1 to n do ans:=ans+d1[i];
46   for i:=1 to m do if p[i]>0 then ans:=ans+d2[i];
47   writeln(ans);
48 end.
PASCAL
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int lb[505][3],f[505],f2[505],p[505];
 4 int n,l,r,x,bo[505],bo2[505],n1,p1[505],m;
 5 long long ans,a[505][505],d[505],d2[505];
 6 void workback(int x)
 7 {
 8     while(x>1){ int y=lb[x][0]; x=lb[x][2]; p[y]=lb[x][1]; }
 9 }
10 int main()
11 {
12     scanf("%d%d%d",&n1,&n,&m); n=max(n,n1);
13     for(int i=1;i<=m;i++)
14     {
15         int j,k,l; scanf("%d%d%d",&j,&k,&l);
16         a[j][k]=l; d[j]=max(d[j],a[j][k]);
17     }
18     for(int ii=1;ii<=n;ii++)
19     {
20         for(int i=1;i<=n;i++)f[i]=f2[i]=0;
21         l=0; r=1; lb[r][1]=ii;
22         while(r>0)
23         {
24             int flag=-1;
25             while(l<r)
26             {
27                 l++; x=lb[l][1]; bo[x]=ii;
28                 for(int i=1;i<=n;i++)if(bo2[i]<ii)
29                 {
30                     if(d[x]+d2[i]-a[x][i]==0)
31                     {
32                         bo2[i]=ii;
33                         if(p[i]==0){ p[i]=x; flag=l; break; }
34                         r++; lb[r][0]=i; lb[r][1]=p[i]; lb[r][2]=l;
35                     }else 
36                     if((f[i]==0)or(d[x]+d2[i]-a[x][i]<d[f[i]]+d2[i]-a[f[i]][i])){ f[i]=x; f2[i]=l; }
37                 }
38                 if(flag!=-1)break;
39             }
40             if(flag!=-1){ workback(flag); break; }
41             long long dd=1000000000000000ll;
42             for(int i=1;i<=n;i++)if(bo2[i]<ii)dd=min(dd,d[f[i]]+d2[i]-a[f[i]][i]);
43             for(int i=1;i<=n;i++)if(bo[i]==ii)d[i]-=dd;
44             for(int i=1;i<=n;i++)if(bo2[i]==ii)d2[i]+=dd;
45             for(int i=1;i<=n;i++)if((bo2[i]<ii)and(d[f[i]]+d2[i]-a[f[i]][i]==0))
46             {
47                 bo2[i]=ii; if(p[i]==0){ p[i]=f[i]; flag=f2[i]; break; }
48                 r++; lb[r][0]=i; lb[r][1]=p[i]; lb[r][2]=f2[i];
49             }
50             if(flag!=-1){ workback(flag); break; }    
51         }
52     }
53     for(int i=1;i<=n;i++)ans+=d[i]+d2[i];
54     printf("%lld\n",ans);
55     for(int i=1;i<=n;i++)p1[p[i]]=i;
56     for(int i=1;i<=n1;i++)if(a[i][p1[i]]>0)printf("%d ",p1[i]);else printf("0 ");
57     printf("\n");
58 }
C++
posted @ 2017-01-05 17:56  GhoStreach  阅读(487)  评论(0编辑  收藏  举报