标签:des style blog http java color
Description
Input
Output
Sample Input
2 2 .m H. 5 5 HH..m ..... ..... ..... mm..H 7 8 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 0 0
Sample Output
2 10 28
很显然的一个二分图,把人看作X,把房子看作Y,这样就构成了二分图,然后人和房子的距离就是人要多少步才能走到房子,这样就构成了一个带权的二分图,然后就是求二分图的最佳完美匹配,注意的是把距离弄成负的,因为求最大,然后跑一边KM算法就可以了,加油!!!这是我的第二道二分图最佳完美匹配题目
#include<map> #include<set> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 0x0f0f0f0f using namespace std; const double pi=acos(-1.0); const double eps=1e-8; typedef pair<int,int>pii; const int maxn=100+10; int W[maxn][maxn],n,c,m;//边的权值 int Lx[maxn],Ly[maxn];//顶标 int lleft[maxn];//右边第i个点的编号 bool S[maxn],T[maxn];//左右第i个点是否标记 struct node { int x,y; }people[maxn],house[maxn]; char str[maxn][maxn]; bool match(int i)//判断是否有增广路 { S[i]=true; for (int j=1;j<=n;j++) if (Lx[i]+Ly[j]==W[i][j] && !T[j]) { T[j]=true; if (!lleft[j] || match(lleft[j])) { lleft[j]=i; return true; } } return false; } void update()//如果有增广路的话,更新 { int a=1<<30; for (int i=1;i<=n;i++) if (S[i]) for (int j=1;j<=n;j++) if (!T[j]) a=min(a,Lx[i]+Ly[j]-W[i][j]); for (int i=1;i<=n;i++) { if (S[i]) Lx[i]-=a; if (T[i]) Ly[i]+=a; } } void k_m() { for (int i=1;i<=n;i++) { lleft[i]=Lx[i]=Ly[i]=0; for (int j=1;j<=n;j++) Lx[i]=max(Lx[i],W[i][j]);//初始可行顶标 } for (int i=1;i<=n;i++) { for (; ;) { for (int j=1;j<=n;j++) S[j]=T[j]=0;//开始都没有标记过 if (match(i)) break; else update(); } } } int find_cost() { int ans=0; for (int i=1;i<=n;i++) ans+=0-W[lleft[i]][i]; return ans; } void init() { int p=0,h=0; for (int i=0;i<c;i++) for (int j=0;j<m;j++) { if (str[i][j]==‘H‘) { house[++h].x=i; house[h].y=j; } if (str[i][j]==‘m‘) { people[++p].x=i; people[p].y=j; } } for (int i=1;i<=p;i++) for (int j=1;j<=h;j++) { W[i][j]=0-(abs(people[i].x-house[j].x)+abs(people[i].y-house[j].y)); } n=p; } int main() { //freopen("in.txt","r",stdin); while (scanf("%d%d",&c,&m)!=EOF && !(c==0 && m==0)) { for (int i=0;i<c;i++) scanf("%s",str[i]); init(); k_m(); printf("%d\n",find_cost()); } //fclose(stdin); return 0; }
我也发现,现在我现在写程序也有点规范了!!!!
poj 2195 Going Home,码迷,mamicode.com
标签:des style blog http java color
原文地址:http://www.cnblogs.com/chensunrise/p/3699849.html