您的位置:首页 > 其它

例题5.24 少林决胜 UVa11383

2015-10-06 23:19 369 查看
1.题目描述:点击打开链接

2.解题思路:本题是KM算法的副产物,在KM算法中,有一个不等式就是L(x)+L(y)>=w(x,y)。算法结束的时候,所有的顶标之和就是最小的。

3.代码:

#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
//#include<cmath>
#include<ctime>
#include<cctype>
#include<list>
#include<complex>
#include<functional>
using namespace std;

#define me(s) memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
#define pb push_back
typedef long long ll;
typedef pair <int,int> P;

const int N=500+10;
const int INF=1e9;

int W

,n;
int Lx
,Ly
;
int Left
;
bool S
,T
;

bool match(int i)
{
S[i]=true;
for(int j=1;j<=n;j++)
if(Lx[i]+Ly[j]==W[i][j]&&!T[j])
{
T[j]=true;
if(!Left[j]||match(Left[j]))
{
Left[j]=i;
return true;
}
}
return false;
}

void update()
{
int a=INF;
for(int i=1;i<=n;i++)if(S[i])
for(int j=1;j<=n;j++)if(!T[j])
a=min(a,Lx[i]+Ly[j]-W[i][j]);
for(int i=1;i<=n;i++)
{
if(S[i])Lx[i]-=a;
if(T[i])Ly[i]+=a;
}
}

void KM()
{
for(int i=1;i<=n;i++)
{
Left[i]=Lx[i]=Ly[i]=0;
for(int j=1;j<=n;j++)
Lx[i]=max(Lx[i],W[i][j]);
}
for(int i=1;i<=n;i++)
{
for(;;)
{
for(int j=1;j<=n;j++)
S[j]=T[j]=0;
if(match(i))break;
else update();
}
}
}

int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&W[i][j]);
KM();
int sum=0;
for(int i=1;i<n;i++)
{
printf("%d ",Lx[i]);
sum+=Lx[i];
}
printf("%d\n",Lx
);
for(int i=1;i<n;i++)
{
printf("%d ",Ly[i]);
sum+=Ly[i];
}
printf("%d\n",Ly
);
printf("%d\n",sum+Lx
+Ly
);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  KM算法