Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
哪位牛人帮忙看看 KM为什么WA啊…………#include<iostream> using namespace std; int n,m,k; const int INF=100000000;// 无穷大 int shkp_need[60][60],supply[60][60],transport[60][60][60];//记录输入 int totneed[60],totsupply[60];//总需求与总供给 int now1[60],now2[60];//每种商品有多少需求与供给 int edgeshkp[60][240],edgesupply[60][240];//记录edge中每个点来自哪个shopkeeper或者supply int edge[60][240][240],match[240]; bool xckd[240],yckd[240]; // Xi与Yi是否在交错树上 bool map[60][240][240]; // 二分图的相等子图, map[i][j] = true 代表Xi与Yj有边 int cost; int init() //初始化与输入 { for(int i=0;i<=k;i++) { totneed[i]=0; totsupply[i]=0; now1[i]=0; now2[i]=0; } for(int i=0;i<=k;i++) { for(int j=0;j<240;j++) { for(int l=0;l<240;l++) edge[i][j][l]=-INF; edgeshkp[i][j]=-1; edgesupply[i][j]=-1; } } for(int i=0;i<n;i++) { for(int j=0;j<k;j++) { scanf("%d",&shkp_need[i][j]); totneed[j]+=shkp_need[i][j]; for(int l=0;l<shkp_need[i][j];l++)//记录edge中每个点来自哪个shopkeeper或者supply { edgeshkp[j][now1[j]]=i; now1[j]++; } } } for(int i=0;i<m;i++) { for(int j=0;j<k;j++) { scanf("%d",&supply[i][j]); totsupply[j]+=supply[i][j]; for(int l=0;l<supply[i][j];l++)//记录edge中每个点来自哪个shopkeeper或者supply { edgesupply[j][now2[j]]=i; now2[j]++; } } } for(int i=0;i<k;i++) { for(int j=0;j<n;j++) { for(int l=0;l<m;l++) scanf("%d",&transport[i][j][l]); } } for(int i=0;i<k;i++) { if(totneed[i]>totsupply[i]) return 0; } cost=0; return 1; } void make()//建图 { memset(map,false,sizeof(map)); memset(xckd,false,sizeof(xckd)); memset(yckd,false,sizeof(yckd)); for(int i=0;i<k;i++) { for(int j=0;j<now1[i];j++) { int shkp=edgeshkp[i][j]; for(int l=0;l<now2[i];l++) { int supply=edgesupply[i][l]; edge[i][j][l]=-transport[i][shkp][supply];//由于求最小权值匹配,所以先取负数 } } } } int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } bool hungary(int kind,int p)//匈牙利算法求最大匹配 { int mx=now2[kind]; for(int i=0;i<mx;i++) { if(!yckd[i]&&map[kind][p][i]) { yckd[i]=true; if(match[i]==-1||hungary(kind,match[i])) { match[i]=p; return true; } if(match[i]!=-1) xckd[match[i]]=true; } } return false; } void KM_Match(int kind)//KM算法求最大权值匹配 { int mx=now1[kind]; int lx[240],ly[240]; for(int i=0;i<mx;i++) { lx[i]=-INF; for(int j=0;j<now2[kind];j++) { lx[i]=max(lx[i],edge[kind][i][j]); ly[j]=0; } } bool perfect=false; while(!perfect) { for(int i=0;i<mx;i++) { for(int j=0;j<now2[kind];j++) { if(lx[i]+ly[j]==edge[kind][i][j]) map[kind][i][j]=true; else map[kind][i][j]=false; } } int live=0; for(int i=0;i<=now2[kind];i++) match[i]=-1; for(int i=0;i<mx;i++) { memset(xckd, false, sizeof(xckd)); memset(yckd, false, sizeof(yckd)); if(hungary(kind,i)) live++; else { xckd[i]=true; break; } } if(live==mx) perfect=true; else { int ex=INF; for(int i=0;i<mx;i++) { for(int j=0;xckd[i]&&j<now2[kind];j++) { if(!yckd[j]) ex=min(ex, lx[i]+ly[j]-edge[kind][i][j]); } } for(int i=0;i<mx;i++) { if(xckd[i]) lx[i]-=ex; } for(int i=0;i<now2[kind];i++) { if(yckd[i]) ly[i]+=ex; } } } } int main() { while(scanf("%d%d%d",&n,&m,&k)!=EOF) { if(n==0&&m==0&&k==0) break; if(init()) { make(); for(int i=0;i<k;i++) { KM_Match(i); for(int j=0;j<now2[i];j++) { if(match[j]!=-1) cost+=edge[i][match[j]][j]; } } printf("%d\n",-cost); } else printf("-1\n"); } return 0; } Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator