poj 2195-Going Home解题报告
2012-05-03 19:20
295 查看
链接:http://poj.org/problem?id=2195
这道题是二分图的最佳匹配问题,而且属于最小匹配,km算法的模版题,题目保证了人数和房子数相等,这是自己第一道km算法题,刚开始对km算法不理解,看各种讲解,终于搞懂了其运行过程和能求出解的原因。km算法保证在整个算法的运行过程中对于匹配x,y保证lx[x]+ly[y]>=w(x,y);最终找到的是lx[x]+ly[y]=w(x,y)的解。
View Code
这道题是二分图的最佳匹配问题,而且属于最小匹配,km算法的模版题,题目保证了人数和房子数相等,这是自己第一道km算法题,刚开始对km算法不理解,看各种讲解,终于搞懂了其运行过程和能求出解的原因。km算法保证在整个算法的运行过程中对于匹配x,y保证lx[x]+ly[y]>=w(x,y);最终找到的是lx[x]+ly[y]=w(x,y)的解。
View Code
#include<iostream> #include<cstdio> #include<cstring> #define N 200 #define inf 0x7fffffff using namespace std; struct point { int x,y; }; point ph ,pm ; int lx ,ly ; int map ; int match ; int usedx ,usedy ,flag; char g ; int abs(int a) { return a>=0?a:-a; } int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int h,m; void build() { int i,j; for(i=1;i<=h;i++) for(j=1;j<=m;j++) map[i][j]=abs(ph[i].x-pm[j].x)+abs(ph[i].y-pm[j].y); } bool dfs(int x) { int i,j,k; usedx[x]=flag; for(i=1;i<=m;i++) { if(usedy[i]!=flag&&lx[x]+ly[i]==map[x][i]) { usedy[i]=flag; if(match[i]==-1||dfs(match[i])) { match[i]=x; return true; } } } return false; } int km() { memset(lx,127,sizeof(lx)); memset(ly,0,sizeof(ly)); build(); flag=0; int res=0; int i,j,k,d; for(i=1;i<=h;i++) for(j=1;j<=m;j++) lx[i]=min(lx[i],map[i][j]);//最大权匹配就取最大值,最小权匹配就取最小值 memset(match,-1,sizeof(match)); for(i=1;i<=h;i++) { flag++; while(!dfs(i)) { d=inf; for(j=1;j<=h;j++) { if(usedx[j]==flag) for(k=1;k<=m;k++) if(usedy[k]!=flag) d=min(map[j][k]-lx[j]-ly[k],d); } for(j=1;j<=h;j++) if(usedx[j]==flag) lx[j]+=d; for(j=1;j<=m;j++) { if(usedy[j]==flag) ly[j]-=d; } flag++; } } for(i=1;i<=m;i++) res+=map[match[i]][i]; return res; } int main() { int r,c,i,j,k; char s; while(scanf("%d%d",&r,&c)&&(r||c)) { h=m=0; for(i=1;i<=r;i++) scanf("%s",g[i]+1); for(i=1;i<=r;i++)//建图过程 for(j=1;j<=c;j++) { if(g[i][j]=='H') { ph[++h].x=i; ph[h].y=j; } if(g[i][j]=='m') { pm[++m].x=i; pm[m].y=j; } } //printf("%d %d\n",h,m); printf("%d\n",km()); } return 0; }
相关文章推荐
- POJ 2195 Going Home(解题报告)
- POJ 2195 解题报告
- POJ - 1837 Balance解题报告
- POJ2739解题报告
- poj 2152解题报告
- POJ 3074 Sudoku 解题报告(Dancing Link)
- POJ 3468 A Simple Problem with Integers (线段树成段更新) 解题报告
- POJ 3673 解题报告
- poj解题报告——1740
- poj2159解题报告
- POJ 3126解题报告
- poj 2195 Going Home (KM算法)
- poj 2195 Going Home (费用流)
- poj 1170-Shopping Offers解题报告
- 【POJ 2195】 Going Home(KM算法求最小权匹配)
- poj解题报告——1003、1005、1799
- poj解题报告——2419
- POJ - 2531 Network Saboteur解题报告(dfs+剪枝)
- POJ-2262-Goldbach's Conjecture 解题报告
- POJ - 2676 Sudoku解题报告(解数独)