您的位置:首页 > 产品设计 > UI/UE

UVA 10746 - Crime Wave - The Sequel

2013-02-14 21:41 363 查看
/*

题意 : n个银行 m个警察 要求每个银行都有警察过去 可以想象成二分图来解决

二分图的最优匹配 求出最小权值 KM算法即可

*/

#include<cstdio>

#include<cstring>

#include<cmath>

int n,m;

double w[30][30];

double lx[30],ly[30],slack;

int left[30],r[30];

bool s[30],t[30];

double M = 10;

bool match(int i)

{

s[i] = true;

double tem;

for(int j = 1; j <= m; j++)

{

if(!t[j])

{

tem = lx[i]+ly[j]-w[i][j];

if(fabs(tem)<1e-9)

{

t[j] = true;

if(left[j]==-1||match(left[j]))

{

r[i] = j;

left[j] = i;

return true;

}

}

else if(tem < slack)

slack = tem;

}

}

return false;

}

void KM()

{

memset(left,-1,sizeof(left));

memset(r,-1,sizeof(r));

memset(lx,0,sizeof(lx));

memset(ly,0,sizeof(ly));

int INF = 1<<30;

for(int i = 1; i <= n; i++)

for(int j = 1; j <= m; j++)

if(lx[i]<w[i][j])

lx[i] = w[i][j];

for(int i = 1; i <= n; i++)

for(;;)

{

slack = INF;

memset(s,0,sizeof(s));

memset(t,0,sizeof(t));

if(match(i))

break;

for(int j = 1; j <= n; j++)

if(s[j])

lx[j] -= slack;

for(int j = 1; j <= m; j++)

if(t[j])

ly[j] += slack;

}

double res=0;

for(int i = 1; i <= n; i++)

res+=M-w[i][r[i]];

printf("%.2lf\n",res/n);

}

int main()

{

double temp;

while(scanf("%d %d",&n,&m)==2)

{

if(!n&&!m) break;

for(int i = 1; i <= n; i++)

for(int j = 1; j <= m; j++)

{

scanf("%lf",&temp);

w[i][j] = M-temp;

}

KM();

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: