poj 3686

来源:互联网 发布:淘宝图像识别 编辑:程序博客网 时间:2024/06/02 13:45

N 个工件要在 M 个机器上加工,有一个 NM 的矩阵描述其加工时间。
同一时间内每个机器只能加工一个工件,问加工完所有工件后,使得平均加工时间最小(等待的时间+加工的时间)

假设某个机器处理了 k 个玩具,时间分别为 a1,a2..,ak

那么该机器耗费的时间为a1+a1+a2+a1+a2+a3.......a1+a2+...ak

a1k+a2(k1)+a3(k2)....+ak
ai玩具在某个机器上倒数第 k 个处理,所耗费全局的时间为 aik

对每个机器,最多可以处理 n 个玩具,拆成 n 个点,1~n 分别代表某个玩具在这个机器上倒数第几个被加工的,对于每个玩具 i,机器 j 中拆的每个点 k,连接一条 w[i][j]k 权值的边


转自http://www.cnblogs.com/Missa/archive/2012/09/29/2708441.html


KM模板


#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>const int MAXN = 55 , MAXM = 55 , MAXY = 2505, INF  = 1<<30;int n, m , nx, ny;int mat[MAXN][MAXM] = {0};int w[MAXN][MAXY] = {0};int lx[MAXN] = {0}, ly[MAXY] = {0};//n toys  m machinesint link[MAXY] = {0},slack[MAXY] = {0};bool visx[MAXN] = {0},visy[MAXY] = {0};void init(){    scanf("%d%d",&n,&m);    for(int i = 1 ; i <= n; i++)      for(int j = 1 ; j <= m ;j++)        scanf("%d",&mat[i][j]);}void build(){    for(int i = 1 ; i <= n ; i++)      for(int j = 1 ; j <= m ; j++)        for(int k = 1 ; k <= n ; k++)        {          w[i][(j-1)*n + k] = -mat[i][j]*k;        }    nx = n , ny = n*m;    }bool find(int x){    visx[x] = true;    for(int y = 1 ; y <= ny ; y++)    {        if(visy[y] == true)continue;        int tmp = lx[x] + ly[y] - w[x][y];        if(!tmp)        {            visy[y] = true;            if(!link[y] || find(link[y])==true)               {link[y] = x;return true;}        }        slack[y] = std::min(slack[y],tmp);    }    return false;}int KM(){    int ret = 0;    memset(link,0,sizeof(link));    memset(ly,0,sizeof(ly));    for(int i = 1 ; i <= nx; i++)    {     lx[i] = -INF;     for(int j = 1 ; j <= ny ; j++)       lx[i] = std::max(lx[i],w[i][j]);      }    for(int x = 1 ; x <= nx; x++)    {      for(int j = 1 ; j <= ny ; j++)        slack[j] = INF;       while(1)      {          memset(visx,false,sizeof(visx));          memset(visy,false,sizeof(visy));          if(find(x)==true)break;          int d = INF;          for(int j = 1 ; j <= ny ; j++)            if(!visy[j])d = std::min(d,slack[j]);          for(int i = 1 ; i <= nx ; i++)            if(visx[i]) lx[i]-=d;          for(int j = 1 ; j <= ny ; j++)            if(!visy[j])slack[j]-=d;            else        ly[j]+=d;        }    }    for(int j = 1; j <= ny ; j++)      if(link[j])ret+=w[link[j]][j];    return -ret;  }int main(){    int T;#ifndef ONLINE_JUDGE        freopen("poj3686.in","r",stdin);    freopen("poj3686.out","w",stdout);#endif    scanf("%d",&T);        while(T--)    {        init(); build();        int cost = KM();        printf("%.6lf\n",(double)cost/n);    }#ifndef ONLINE_JUDGE    fclose(stdin);    fclose(stdout);#endif     return 0;       }
0 0