匈牙利算法与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.
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 }
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.
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 }