可以KM,也可以费用流,最近学费用流,所以用一下,debug真浪费时间,以为spfa有问题,原来是计数时出错。。。囧啊,菜啊,话说poj 2516到现在还不知道wa哪里,抓狂啊!!!
#define inf 1<<30
#define N 222
int cap[N][N];
int cost[N][N];
int pre[N];
int dis[N];
bool vis[N];
int minc;
char str[110][110];
int min(int a,int b){return a>b?b:a;}
void spfa(int s,int t){
queue<int> qq;
int i,j;
while(1){
for(i=s;i<=t;i++){
vis[i] = 0;
dis[i] = inf;
}
dis[s] = 0;
qq.push(s);
vis[s] = 1;
while(!qq.empty()){
int u = qq.front();
qq.pop();
vis[u] = 0;
for(int v=s;v<=t;v++){
if(cap[u][v] && dis[u] + cost[u][v] < dis[v]){
dis[v] = dis[u] + cost[u][v];
pre[v] = u;
if(!vis[v]){
vis[v] = 1;
qq.push(v);
}
}
}
}
if(dis[t] == inf){
return ;
}
int a = inf;
for(int u=t;u!=s;u=pre[u]){
a = min(a,cap[pre[u]][u]);
}
for(int u=t;u!=s;u=pre[u]){
cap[pre[u]][u] -= a;
cap[u][pre[u]] += a;
}
minc += dis[t]*a;
}
return ;
}
struct node{
int r,c;
}mm[N/2],hh[N/2];
int cntm ;
int cnth ;
void work(){
int i,j;
int s = 0,t = cntm + cnth + 1;
minc =0;
memset(cap,0,sizeof(cap));
memset(cost,0,sizeof(cost));
for(i=1;i<=cntm;i++){
cap[s][i] = 1;//每条边容量为1,最后肯定是满流的
cost[s][i] = 0;
}
for(i=1;i<=cnth;i++){
cap[i+cntm][t] = 1;
cost[i+cntm][t] = 0;
}
for(i=1;i<=cntm;i++){
for(j=1;j<=cnth;j++){
cap[i][j+cntm] = 1;
cost[i][j+cntm] = abs(mm[i].r - hh[j].r) + abs(mm[i].c - hh[j].c);
cost[j+cntm][i] = -cost[i][j+cntm];//注意要取反
}
}
spfa(s,t);
printf("%d\n",minc);
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m) && (n+m)){
int i,j;
for(i=1;i<=n;i++){
scanf("%s",str[i]+1);
}
cntm = 0;
cnth = 0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(str[i][j] == 'm'){
mm[++cntm].r = i;
mm[cntm].c = j;
} else if(str[i][j] == 'H'){
hh[++cnth].r = i;
hh[cnth].c = j;
}
}
}cout<<cntm<<endl;
work();
}
return 0;
}
本文深入探讨了费用流算法的实现细节,并通过一个具体的示例程序展示了如何使用该算法解决匹配问题。文章中详细解释了SPFA算法的应用以及如何进行代码调试,还特别提到了在实现过程中容易遇到的问题。
1375

被折叠的 条评论
为什么被折叠?



