hdu2426 Interesting Housing Problem (KM邻接表)
来源:互联网 发布:失踪的宝贝知乎 编辑:程序博客网 时间:2024/05/17 04:31
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2426
题解:最大权值单边(nx的每一个点都在匹配中)完备匹配,不能把学生安排在rate小于0的房间,负权边舍弃。
#include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f #define MAXN 502 int w[MAXN][MAXN],match[MAXN]; int lx[MAXN],ly[MAXN],slack[MAXN]; int visitx[MAXN],visity[MAXN]; int nx,ny;int find(int x){ int i,temp; visitx[x]=1; for(i=0;i<ny;++i) { if(visity[i]) continue; temp=lx[x]+ly[i]-w[x][i]; if(temp==0) { visity[i]=1; if(match[i]==-1||find(match[i])) { match[i]=x; return 1; } } else if(slack[i]>temp) { slack[i]=temp; } } return 0; } int KM() { int i,j,d,sum,cnt; memset(ly,0,sizeof(ly)); memset(match,-1,sizeof(match)); for(i=0;i<nx;++i) {//lx初始化为与它关联边中最大的 lx[i]=w[i][0]; for(j=1;j<ny;++j) if(w[i][j]>lx[i]) lx[i]=w[i][j]; } for(i=0;i<nx;++i) { for(j=0;j<ny;++j) slack[j]=INF; while(1) { memset(visitx,0,sizeof(visitx)); memset(visity,0,sizeof(visity)); if(find(i)) break; d=INF; for(j=0;j<ny;++j) { if(!visity[j]&&d>slack[j]) d=slack[j]; } for(j=0;j<nx;++j) { if(visitx[j]) lx[j]-=d; } for(j=0;j<ny;++j) { if(visity[j]) ly[j]+=d; else slack[j]-=d; } } } sum=0;cnt=0; for(i=0;i<ny;++i) { if(match[i]==-1||w[match[i]][i]==(~INF+1)) continue;sum+=w[match[i]][i];cnt++;} if(cnt!=nx)//nx个学生是否都安排房间 return -1;elsereturn sum;} int main(){int E,s,r,val,ans,cases=1;while(scanf("%d %d %d",&nx,&ny,&E)!=EOF){for(s=0;s<=nx;++s){for(r=0;r<=ny;++r)w[s][r]=(~INF+1);}if(E==0){printf("Case %d: -1\n",cases++);continue;}while(E--){scanf("%d %d %d",&s,&r,&val);if(val>=0)w[s][r]=val;}ans=KM();printf("Case %d: %d\n",cases++,ans);}return 0;}
#include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f #define MAXN 501 //邻接表struct node{int from,to,next,val;}edge[MAXN*MAXN];int match[MAXN],head[MAXN],tot; int lx[MAXN],ly[MAXN],slack[MAXN]; int visitx[MAXN],visity[MAXN]; int nx,ny;void addEdge(int x,int y,int val){edge[tot].from=x;edge[tot].to=y;edge[tot].val=val;edge[tot].next=head[x];head[x]=tot++;}int find(int x){ int i,temp,y; visitx[x]=1; for(i=head[x];i!=-1;i=edge[i].next) { y=edge[i].to;if(visity[y]) continue; temp=lx[x]+ly[y]-edge[i].val; if(temp==0) { visity[y]=1; if(match[y]==-1||find(match[y])) { match[y]=x; return 1; } } else if(slack[y]>temp) { slack[y]=temp; } } return 0; } int KM() { int i,j,d,sum,cnt; memset(ly,0,sizeof(ly)); memset(match,-1,sizeof(match));for(i=0;i<nx;++i) { for(j=0;j<ny;++j) slack[j]=INF; while(1) { memset(visitx,0,sizeof(visitx)); memset(visity,0,sizeof(visity)); if(find(i)) break; d=INF; for(j=0;j<ny;++j) { if(!visity[j]&&d>slack[j]) d=slack[j]; } for(j=0;j<nx;++j) { if(visitx[j]) lx[j]-=d; } for(j=0;j<ny;++j) { if(visity[j]) ly[j]+=d; else slack[j]-=d; } } } sum=0;cnt=0; for(i=0;i<ny;++i) { if(match[i]!=-1){cnt++;for(j=head[match[i]];j!=-1;j=edge[j].next){if(edge[j].to==i){sum+=edge[j].val;break;}}}} if(cnt!=nx)//nx个学生是否都安排房间 return -1;elsereturn sum;} int main(){int i,E,s,r,val,ans,cases=1;while(scanf("%d %d %d",&nx,&ny,&E)!=EOF){if(E==0){printf("Case %d: -1\n",cases++);continue;}tot=0;memset(head,-1,sizeof(head));memset(lx,-1,sizeof(lx));while(E--){scanf("%d %d %d",&s,&r,&val);if(val>=0){addEdge(s,r,val);if(val>lx[s])lx[s]=val;}}for(i=0;i<nx;++i){if(lx[i]<0)break;}if(i<nx){printf("Case %d: -1\n",cases++);continue;}ans=KM();printf("Case %d: %d\n",cases++,ans);}return 0;}
- hdu2426 Interesting Housing Problem (KM邻接表)
- HDU2426 Interesting Housing Problem(KM匹配 )
- hdu2426 Interesting Housing Problem
- HDU2426-Interesting Housing Problem KM 稍微复杂一点
- Interesting Housing Problem----KM
- hdu2426——Interesting Housing Problem
- hdu 2426 Interesting Housing Problem (KM)
- hdu 2426 Interesting Housing Problem (KM算法)
- hdu 2426 Interesting Housing Problem(KM)
- hdu 2426 Interesting Housing Problem【KM】
- HDU 2426 Interesting Housing Problem(KM完美匹配)
- hdu 2426 Interesting Housing Problem 最大权值 && KM算法
- 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算法
- 海量数据相似度计算之simhash短文本查找
- 模拟集成电路设计的九个层次
- 前序、中序、后序遍历的多种非递归实现
- JAVA中JButton常用设置
- 关于协方差矩阵的理解
- hdu2426 Interesting Housing Problem (KM邻接表)
- Linux 虚拟鼠标,键盘
- 28. 不要将你的程序钉成竖直
- linux环境下利用autotools工具自动生成make file
- hdu-1232-畅通工程//nyoj-608-畅通工程
- 设计模式之单例模式
- 互联网创业如何与传统行业人士合作?
- Expression Studio 4 Ultimate 中文版以及密钥(转)
- 判断素数问题(C语言实现)