• KM模板


    var
     n,m,i,j:longint;
     ans:int64;
     sel,lx,ly,slack:array[1..100] of int64;
     a:array[1..100,1..100] of int64;
     visx,visy:array[1..100] of boolean;
    
     function dfs(po:longint):boolean;
     var
      i:longint;
      t:int64;
       begin
         visx[po]:=true;
    
         for i:=1 to m do
           if visy[i]=false then
             begin
               t:=lx[po]+ly[i]-a[po,i];
               if t=0 then
                 begin
                   visy[i]:=true;
                   if sel[i]=0 then
                    begin
                      sel[i]:=po;
                      exit(true);
                    end else
                   if dfs(sel[i]) then
                     begin
                       sel[i]:=po;
                       exit(true);
                     end;
                 end else
                 if slack[i]>t then slack[i]:=t;
             end;
         exit(false);
       end;
    
     procedure km;
     var
      i,j:longint;
      d:int64;
       begin
         for i:=1 to n do
           lx[i]:=-100000*maxlongint;
    
    
    
         for i:=1 to n do
           for j:=1 to m do
             if a[i,j]>lx[i] then lx[i]:=a[i,j];
    
         for i:=1 to n do
           begin
             while true do
               begin
                 fillchar(visx,sizeof(visx),0);
                 fillchar(visy,sizeof(visy),0);
                 for j:=1 to m do
                 slack[j]:=100000*maxlongint;
    
                 if dfs(i) then break;
    
                 d:=100*maxlongint;
    
                 for j:=1 to  m do
                   if (visy[j]=false) and (slack[j]<d) then d:=slack[j];
    
                 for j:=1 to n do
                   if visx[j] then dec(lx[j],d);
    
                 for j:=1 to m do
                   if visy[j] then inc(ly[j],d);
               end;
           end;
       end;
    
      begin
        read(n,m);
    
        for i:=1 to n do
          for j:=1 to m do
           begin
             read(a[i,j]);
           end;
    
        km;
    
        for i:=1 to n do ans:=ans+lx[i];
    
        for i:=1 to  m do ans:=ans+ly[i];
    
      writeln(ans);
      end.
    #include<cstdio> #include<iostream> #include<cmath> using namespace std; int m,n,k; int visx[1001],visy[1001],sel[1001]; long long lx[1001],ly[1001],a[1001][1001],slack[1001]; int dfs(int po){ visx[po]=1; for (int i=1;i<=m;i++) if (visy[i]==0){ long long t=lx[po]+ly[i]-a[po][i]; if (t==0){ visy[i]=1; if ((sel[i]==-1)||(dfs(sel[i]))){ sel[i]=po; return(1); } }else slack[i]=min(slack[i],t); } return(0); } void km(){ for (int i=1;i<=n;i++) lx[i]=-1e10; for (int i=1;i<=m;i++) ly[i]=0; for (int i=1;i<=m;i++) sel[i]=-1; for (int i=1;i<=n;i++) for(int j=1;j<=m;j++) lx[i]=max(lx[i],a[i][j]); for (int i=1;i<=n;i++) while (1){ for (int j=1;j<=n;j++) visx[j]=0; for (int j=1;j<=m;j++) visy[j]=0,slack[j]=1e10; if (dfs(i)) break; long long d=1e10; for (int j=1;j<=m;j++) if (visy[j]==0) d=min(d,slack[j]); for (int j=1;j<=n;j++) if (visx[j]) lx[j]-=d; for (int j=1;j<=m;j++) if (visy[j]) ly[j]+=d; } } int main(){ int T; scanf("%d",&T); while (T--){ scanf("%d%d%d",&n,&m,&k); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) a[i][j]=0; for (int i=1;i<=k;i++){ int x,l,p,r; scanf("%d%d%d%d",&x,&l,&r,&p); for (int j=l;j<=r;j++) a[x][j]=p; } km(); long long ans1=0; for (int i=1;i<=n;i++) ans1+=lx[i]; for (int i=1;i<=m;i++) ans1+=ly[i]; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) a[i][j]*=-1; km(); long long ans2=0; for (int i=1;i<=n;i++) ans2-=lx[i]; for (int i=1;i<=m;i++) ans2-=ly[i]; if (ans1==ans2) printf("YES ");else printf("NO "); } }

    求最小值所有边取相反数后KM,输出有答案的相反数

    求最小乘积先求对数再KM

  • 相关阅读:
    微软小娜APP的案例分析
    嵌入式第12次实验
    嵌入式第11次实验
    嵌入式第10次实验报告
    嵌入式第9次实验
    软工 小组作业(第二次)
    嵌入式软件设计第8次实验报告-140201236-沈樟伟
    5月17下
    5月17上
    5月15上午
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/5212818.html
Copyright © 2020-2023  润新知