• 【UOJ 80】 二分图最大权匹配


    【分析】

      之前打的那种KM会TLE。。。

      why??明明说n^3的啊?

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 410
      9 #define Maxm 160010
     10 // #define INF 0x7fffffff
     11 #define LL long long
     12 const LL INF=1LL<<62;
     13 
     14 LL mymin(LL x,LL y) {return x<y?x:y;}
     15 LL mymax(LL x,LL y) {return x>y?x:y;}
     16 
     17 int N;
     18 
     19 int n,m;
     20 int match[Maxn],op[Maxn];
     21 LL eg[Maxn][Maxn],lx[Maxn],ly[Maxn],slack[Maxn];
     22 int visx[Maxn],visy[Maxn],pre[Maxn];
     23 
     24 void mh(int y)
     25 {
     26     for(int x,z;y>0;y=z)
     27     {
     28         x=pre[y];z=op[x];
     29         op[x]=y;match[y]=x;
     30     }
     31 }
     32 
     33 int nt;
     34 void ffind(int st)
     35 {
     36     for(int i=1;i<=N;i++) slack[i]=INF;
     37     queue<int> q;nt++;
     38     q.push(st);visx[st]=nt;
     39     while (1)
     40     {
     41         while(!q.empty())
     42         {
     43             int x=q.front();q.pop();
     44             for(int y=1;y<=N;y++)
     45              if(visy[y]!=nt)
     46              {
     47                  if(lx[x]+ly[y]==eg[x][y])
     48                  {
     49                      pre[y]=x;
     50                      if(!match[y]) {mh(y);return;}
     51                      q.push(match[y]);
     52                      visx[match[y]]=nt;visy[y]=nt;
     53                  }
     54                  else if(slack[y]>lx[x]+ly[y]-eg[x][y]) 
     55                     slack[y]=lx[x]+ly[y]-eg[x][y],pre[y]=x;
     56              }
     57         }
     58         LL delta=INF;
     59         for(int y=1;y<=N;y++) if(visy[y]!=nt) delta=mymin(delta,slack[y]);
     60         for(int i=1;i<=N;i++)
     61         {
     62             if(visx[i]==nt) lx[i]-=delta;
     63             if(visy[i]==nt) ly[i]+=delta;
     64             else slack[i]-=delta;
     65         }
     66         for(int i=1;i<=N;i++) if(visy[i]!=nt&&slack[i]==0)
     67         {
     68             if(!match[i]) {mh(i);return;}
     69             q.push(match[i]);
     70             visx[match[i]]=nt;visy[i]=nt;
     71         }
     72     }
     73 }
     74 
     75 
     76 LL KM()
     77 {
     78     memset(visx,0,sizeof(visx));
     79     memset(visy,0,sizeof(visy));
     80     for (int i=1;i<=N;i++) lx[i]=ly[i]=0,op[i]=match[i]=0;
     81     for (int i=1;i<=N;i++)
     82      for (int j=1;j<=N;j++)
     83       lx[i]=mymax(lx[i],eg[i][j]);
     84     for (int i=1;i<=N;i++) ffind(i);
     85 }
     86 
     87 void output()
     88 {
     89     LL ans=0;
     90     for(int i=1;i<=N;i++) ans+=lx[i]+ly[i];
     91     printf("%lld
    ",ans);
     92     for(int i=1;i<=n;i++) if(eg[i][op[i]]!=0) printf("%d ",op[i]);
     93     else printf("0 ");printf("
    ");
     94 }
     95 
     96 void init()
     97 {
     98     int l;
     99     memset(eg,0,sizeof(eg));
    100     scanf("%d%d%d",&n,&m,&l);
    101     for(int i=1;i<=l;i++)
    102     {
    103         int x,y;
    104         LL c;
    105         scanf("%d%d%lld",&x,&y,&c);
    106         eg[x][y]=mymax(eg[x][y],c);
    107     }
    108     N=mymax(n,m);
    109 }
    110 
    111 int main()
    112 {
    113     init();
    114         KM();
    115     output();
    116         return 0;
    117 }
    View Code
  • 相关阅读:
    突破
    leetcode刷题 538~
    leetcode刷题 519~
    Docker练习之镜像更新方法1
    十二 Linux之tar解压缩
    十一 Linux软件包管理yum
    十 Linux指令之grep
    九 linux指令之find
    八 Linux ps指令查看进程和kill杀进程
    七 Linux top命令
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6492788.html
Copyright © 2020-2023  润新知