码迷,mamicode.com
首页 > 编程语言 > 详细

KM算法

时间:2015-10-02 23:51:05      阅读:447      评论:0      收藏:0      [点我收藏+]

标签:

hdu2255:奔小康赚大钱

○| ̄|_○| ̄|_○| ̄|_。终于自己写出来了,虽然是模板题。首先是正确性的证明然后就是O(n^3)的优化,然而我就是这么弱智,弄了一个多小时才弄完;

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
const int nmax=305;
const int inf=(1<<30);
int lx[nmax],ly[nmax],s[nmax],t[nmax],f[nmax],slack[nmax],n,v[nmax][nmax];
int read(){
    int x=0;
    char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)){
        x=x*10+c-0;
        c=getchar();
    }
    return x;
}
int find(int x){
    s[x]=1;
    rep(i,n)
      if(!t[i]){
          int a=lx[x]+ly[i]-v[x][i];
          if(!a){
              t[i]=1;
              if(f[i]<0||find(f[i])){
                  f[i]=x;
                  return 1;
              }
          }
          else 
            slack[i]=min(slack[i],a);
      }
    return false;
}
int km(){
    clr(lx,-0x3f);clr(ly,0);clr(f,-1);
    rep(i,n)
      rep(j,n)
        lx[i]=max(lx[i],v[i][j]);
    rep(i,n){
        rep(j,n) slack[j]=inf;
        while(1){
            clr(s,0);clr(t,0);
            if(find(i))
              break;
            int a=inf;
            rep(j,n)
              if(!t[j])
                a=min(slack[j],a);
            rep(j,n)
              if(s[j])
                lx[j]-=a;
            rep(j,n)
              if(t[j])
                ly[j]+=a;
              else
                slack[j]-=a;
        }
    }
    int ans=0;
    rep(i,n)
      if(f[i])
        ans+=v[f[i]][i];
    return ans;
}
int main(){
    while(~scanf("%d",&n)){
        rep(i,n)
          rep(j,n)
            v[i][j]=read();
        printf("%d\n",km());
    }
    return 0;
}

 

KM算法

标签:

原文地址:http://www.cnblogs.com/20003238wzc--/p/4852845.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!