Interesting Housing Problem----KM
来源:互联网 发布:腾讯云申请域名绿标 编辑:程序博客网 时间:2024/05/17 21:57
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2426
注:
1) 二分图中边权为负值时,不匹配 (he still wants to design a creative plan such that no student is assigned to a room he/she dislikes)
2) KM算法中如果无法进行匹配成功,就会进入死循环 (所以我选择用最大二分匹配 先进行匹配)
3) 还有就是如果是邻接矩阵储存的话,要考虑到矩阵的初始化
源代码:
/*==============================================================================*\二分图最佳匹配(kuhn munkras算法)最大权匹配/最小权匹配,复杂度O(n^3)\*==============================================================================*/#include <stdio.h>#include <string.h>#include <algorithm>#define N 505 //N是X的顶点数最大值 M是Y的顶点数最大值 #define M 5005#define INF 1e9#define fin -10001 //g[][]的初值,绝对值大于边权的最大值using namespace std;int u,v,w,e;int g[N][M],nx,ny; //需要初始化 nx是X的顶点数 ny是Y的顶点数int mx[N],my[M],lx[N],ly[M]; //lx[],ly[]为KM算法中Xi与Yi的顶点标号 mx[]是匹配后X中对应的Y的顶点编号 my[]是匹配后Y中对应的X的顶点编号bool sx[N],sy[N]; //标记是否在交错树上int prev[N],slack[N]; //prev[i]为Y中i点在交错树上的前点;slack为松弛量int q[2*N],head,tail;bool chk[N]; //标记数组bool search(int u){ for(int v=0;v<ny;v++) if(g[u][v]>-1&&!chk[v]) { chk[v]=true; if(my[v]==-1||search(my[v])) { my[v]=u; mx[u]=v; return true; } } return false;}int Maxmatch(){ int ret=0; memset(mx,-1,sizeof(mx)); memset(my,-1,sizeof(my)); for(int u=0;u<nx;u++) if(mx[u]==-1) { memset(chk,false,sizeof(chk)); if(search(u)) ret++; } return ret;}void augment(int v){ //增广 while(v!=-1){ int pv=mx[prev[v]]; mx[prev[v]]=v; my[v]=prev[v];v=pv; }}bool bfs(){ while(head!=tail){ int p=q[head++],u=p>>1; if(p & 1){ if(my[u]==-1){ augment(u);return true; } else { q[tail++]=my[u]<<1; sx[my[u]]=true; } } else for(int i=0;i<ny;i++) if(sy[i]) continue; else if(lx[u]+ly[i]!=g[u][i]){ int ex=lx[u]+ly[i]-g[u][i]; if(slack[i]>ex){ slack[i]=ex; prev[i]=u; } } else { prev[i]=u; sy[i]=true; q[tail++]=i*2+1; } } return false;}int KMmatch(bool maxsum ){ //默认为最大权匹配 int i,j,ex,cost=0; if(!maxsum) for(i=0;i<nx;i++) for(j=0;j<ny;j++) g[i][j]*=-1; memset(mx,-1,sizeof(mx)); memset(my,-1,sizeof(my)); memset(ly,0,sizeof(ly)); for(i=0;i<nx;i++) for(lx[i]=-INF,j=0;j<ny;j++) lx[i]=max(lx[i],g[i][j]); for(int live=0;live<nx;live++){ memset(sx,0,sizeof(sx)); memset(sy,0,sizeof(sy)); for(i=0;i<ny;i++)slack[i]=INF; head=tail=0; q[tail++]=live*2; sx[live]=true; while(!bfs()){ for(ex=INF,i=0;i<ny;i++) if(!sy[i]) ex=min(ex,slack[i]); for(i=0;i<nx;i++) if(sx[i])lx[i]-=ex; for(j=0;j<ny;j++){ if(sy[j])ly[j]+=ex;slack[j]-=ex;} for(i=0;i<ny;i++) if(!sy[i] && slack[i]==0){q[tail++]=i*2+1;sy[i]=true;} } } if(!maxsum) for(i=0;i<nx;i++) for(j=0;j<ny;j++) g[i][j]*=-1; for(i=0;i<nx;i++)cost+=g[i][mx[i]]; return cost;}int main(){ int k=0; //freopen("D:\\a.txt","r",stdin); while(~scanf("%d %d %d",&nx,&ny,&e)) { k++; memset(g,fin,sizeof(g)); for(int i=0;i<e;i++) { scanf("%d %d %d",&u,&v,&w); if(w>=0) g[u][v]=w; } if(Maxmatch()!=nx) printf("Case %d: -1\n",k); else printf("Case %d: %d\n",k,KMmatch(true)); }}
几组测试数据:
2 2 4
0 0 1
0 1 4
1 0 -1
1 1 1
2 1 2
0 0 2
1 0 3
3 3 3
0 0 8
1 0 9
2 2 10
- Interesting Housing Problem----KM
- hdu 2426 Interesting Housing Problem (KM)
- hdu2426 Interesting Housing Problem (KM邻接表)
- hdu 2426 Interesting Housing Problem (KM算法)
- hdu 2426 Interesting Housing Problem(KM)
- HDU2426 Interesting Housing Problem(KM匹配 )
- hdu 2426 Interesting Housing Problem【KM】
- HDU 2426 Interesting Housing Problem(KM完美匹配)
- hdu 2426 Interesting Housing Problem 最大权值 && KM算法
- HDU2426-Interesting Housing Problem KM 稍微复杂一点
- hdu2426 Interesting Housing Problem
- HDU 2426 Interesting Housing Problem
- HDU-2426 Interesting Housing Problem
- hdu 2426 Interesting Housing Problem
- HDU 2426 Interesting Housing Problem
- HDU 2426 Interesting Housing Problem
- HDU 2426 Interesting Housing Problem 最小费用最大流 or KM算法
- HDU 2426 Interesting Housing Problem 二分匹配(KM模板)或者最小费用最大流
- IAR环境中实现数据或函数的定位
- 近期学习html+css
- linux的信号机制
- PHP类分享:session保存到数据库
- ofproperty
- Interesting Housing Problem----KM
- 大话设计模式中简单工厂模式的计算器实例的C++代码
- 菜鸟列举小例浅谈数据库管理之-------数据库的 增、删、改、查
- dedecms 文档ID: XX – 模板文件不存在,无法解析文档!
- 关于叙述Ubuntu 8.10常用软件,设置,配置(一)
- 设计模式php实例:单例模式
- 关于叙述Ubuntu 8.10常用软件,设置,配置(二)
- 天气预报+定时短信分享(Google Weather API)
- laplacian of gaussian filter