zoukankan      html  css  js  c++  java
  • HDU 2255 & KM模板

    题意:

      一张完备二分图求最优完备匹配。

    SOL:

      这题就不讲什么sol了。。。毕竟是裸的KM,不会的话可以看老人家的大白鼠,一些问题看代码注释。讲讲经历(悲惨的经历)

      刚打完,自信地交上去发现MLE...一脸大雾...然后才开始看数据..300^4啊...看起来会炸的样子,那么加个优化好了。还是MLE!真是奇了怪了。然后就在提交里看别人是不是用的邻接表——清一色邻接矩阵!再想想KM搞的都是完备图啊邻接表和邻接矩阵用起来没什么不同。那么没问题啊?然后交来交去交了8次...直到zyh大神——虽然他从不用KM,但是他居然一眼道出真相——没看到递归啊。

      woc!!!HDU!!!显然我是爆栈了!!终于经历了一次爆栈的体验啊。。。也不枉此生了。

    CODE:

    /*==========================================================================
    # Last modified: 2016-02-16 18:17
    # Filename: hdu2255.cpp
    # Description: 
    ==========================================================================*/
    #define me AcrossTheSky 
    #include <cstdio> 
    #include <cmath> 
    #include <ctime> 
    #include <string> 
    #include <cstring> 
    #include <cstdlib> 
    #include <iostream> 
    #include <algorithm> 
      
    #include <set> 
    #include <map> 
    #include <stack> 
    #include <queue> 
    #include <vector> 
    #define lowbit(x) (x)&(-x) 
    #define INF 0x3f3f3f3f
    #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) 
    #define FORP(i,a,b) for(int i=(a);i<=(b);i++) 
    #define FORM(i,a,b) for(int i=(a);i>=(b);i--) 
    #define ls(a,b) (((a)+(b)) << 1) 
    #define rs(a,b) (((a)+(b)) >> 1) 
    #define maxn 310
    using namespace std; 
    typedef long long ll; 
    typedef unsigned long long ull; 
    /*==================split line==================*/ 
    int n;
    int slack[maxn],w[maxn][maxn],lx[maxn],ly[maxn],link[maxn]; //lx,ly表示节点函数,link表示T集每点对应的S集点
    bool S[maxn],T[maxn]; //是否在相等子图中
    
    bool match(int x){
    	S[x]=true;
    	FORP(i,1,n){
    		if (T[i]) continue;
    		if (lx[x]+ly[i]==w[x][i]){		
    				T[i]=true;
    				if (!link[i] || match(link[i])){
    					link[i]=x;
    					return true;
    				}
    			}
    		else slack[i]=min(slack[i],lx[x]+ly[i]-w[x][i]); //用slack计算出松弛量
    	}
    	return false;
    }
    void updata(){
    	int a=INF;
    	FORP(j,1,n) if (!T[j])
    		a=min(a,slack[j]);
    	FORP(i,1,n) {
    		if (S[i]) lx[i]-=a;
    		if (T[i]) ly[i]+=a;
    		else slack[i]-=a;
    	}
    	return;
    }
    void KM(){
    	memset(lx,0,sizeof(lx));
    	memset(ly,0,sizeof(ly));
    	FORP(i,1,n){
    		link[i]=0;
    		//S[i]=T[i]=false;
    		FORP(j,1,n)
    			lx[i]=max(lx[i],w[i][j]);
    	}
    	FORP(i,1,n){ //这里要循环N次我一直有点雾...
    		FORP(j,1,n) slack[j]=INF;
    		while(1){
    			memset(S,false,sizeof(S));
    			memset(T,false,sizeof(T));
    			if (match(i)) break;
    				else updata();
    		}
    	}
    }
    int main(){
    	while (scanf("%d",&n)==1){
    		FORP(i,1,n)
    			FORP(j,1,n) {
    				scanf("%d",&w[i][j]); 
    		}
    		KM();
    		int ans=0;
    		FORP(i,1,n) if (link[i]) //计算边权和
    			ans+=w[link[i]][i];
    		printf("%d
    ",ans);
    	}
    }
    
    Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.
  • 相关阅读:
    Exception handling 异常处理的本质
    一个人运气不好怎么办?做什么事能够马上改变运气?
    autoreleasing on a thread
    Tagged Pointer
    Objective-C 引用计数原理
    oc引用计数原理-引用计数相关变化
    黑箱中的 retain 和 release
    黑幕背后的Autorelease
    自动释放池的前世今生 ---- 深入解析 autoreleasepool
    Exceptions and Errors on iOS
  • 原文地址:https://www.cnblogs.com/YCuangWhen/p/5194215.html
Copyright © 2011-2022 走看看