zoukankan      html  css  js  c++  java
  • HDU [P1533]

    二分图带权最小匹配(朴素)

    只要换几个不等号的方向就行,不需要变换权值的正负

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    int n,m,wei[105][105],lx[105],ly[105],match[105];
    bool fx[105],fy[105];
    struct point{
    	int x,y;
    }men[105],hou[105];
    bool hungarian(int u){
    	fx[u]=1;
    	for(int v=1;v<=m;v++){
    		if(!fy[v]&&(lx[u]+ly[v]==wei[u][v])){
    			fy[v]=1;
    			if(!match[v]||hungarian(match[v])){
    				match[v]=u;
    				return 1;
    			}
    		}
    	}
    	return 0;
    }
    int main(){
    	while(1){
    		int row,col;
    		cin>>row>>col;
    		if(!row&&!col) break;
    		n=m=0;
    		for(int i=1;i<=row;i++){
    			for(int j=1;j<=col;j++){
    				char t;
    				scanf(" %c ",&t);	
    				if(t=='m') men[++n].x=i,men[n].y=j;
    				if(t=='H') hou[++m].x=i,hou[m].y=j;
    			}
    		}
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=m;j++){
    			//	printf("%d %d %d %d
    ",men[i].x,men[i].y,hou[j].x,hou[j].y); 
    				wei[i][j]=abs(men[i].x-hou[j].x)+abs(men[i].y-hou[j].y);
    			}
    		}
    		memset(lx,0x3f,sizeof(lx));                  //
    		memset(ly,0,sizeof(ly));
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=m;j++){
    				lx[i]=min(lx[i],wei[i][j]);
    			}
    		}
    		memset(match,0,sizeof(match));
    		for(int i=1;i<=n;i++){
    			while(1){
    				memset(fx,0,sizeof(fx));
    				memset(fy,0,sizeof(fy));
    				if(hungarian(i)) break;
    				int mi=-0x3f3f3f3f;           //
    				for(int k=1;k<=n;k++){
    					if(fx[k]){
    						for(int j=1;j<=m;j++){
    							if(!fy[j]&&(lx[k]+ly[j]-wei[k][j])>mi){   //
    								mi=lx[k]+ly[j]-wei[k][j];
    							}
    						}
    					}
    				}
    				for(int i=1;i<=n;i++){
    					if(fx[i]) lx[i]-=mi;
    				}
    				for(int i=1;i<=m;i++){
    					if(fy[i]) ly[i]+=mi;
    				}
    			}
    		}
    		int ans=0;
    		for(int i=1;i<=m;i++){
    			if(match[i]) ans+=wei[match[i]][i];
    			//cout<<ans<<endl;
    		}
    		cout<<ans<<endl;
    	}
    }
    
  • 相关阅读:
    高精度不会的迅速暴击此处
    高精度不会的迅速暴击此处
    codevs3243:区间翻转,线段树
    codevs3243:区间翻转,线段树
    codevs3243:区间翻转,线段树
    [NOIP2010]关押罪犯
    [NOIP2010]关押罪犯
    [NOIP2010]关押罪犯
    [UVALive 6693]Flow Game计算几何,线代相交
    2017 省赛选拨 火车入站 CSU 1757 模拟
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8302083.html
Copyright © 2011-2022 走看看