Interesting Housing Problem
题意:n个人,m个房间,安排住宿。要求每个人不能分到不喜欢的房间,且使满意度最大。
不用slack几乎要超时~
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxn=550; 5 6 int c[maxn][maxn]; 7 int vb[maxn],vg[maxn],eb[maxn],eg[maxn]; 8 int mc[maxn]; 9 int slack[maxn]; 10 int n,m,r; 11 12 int dfs(int id){ 13 vg[id]=1; 14 for(int i=0;i<m;i++){ 15 int gap=eg[id]+eb[i]-c[id][i]; 16 if(vb[i]) continue; 17 if(gap==0){ 18 vb[i]=1; 19 if(mc[i]==-1||dfs(mc[i])){ 20 mc[i]=id; 21 return 1; 22 } 23 } 24 else slack[i]=min(slack[i],gap); 25 } 26 return 0; 27 } 28 29 int KM() 30 { 31 memset(mc,-1,sizeof(mc)); 32 memset(eb,0,sizeof(eb)); 33 for(int i=0;i<n;i++){ 34 eg[i]=c[i][0]; 35 for(int j=1;j<m;j++) 36 eg[i]=max(eg[i],c[i][j]); 37 } 38 39 for(int i=0;i<n;i++){ 40 memset(slack,inf,sizeof(slack)); 41 while(1){ 42 memset(vb,0,sizeof(vb)); 43 memset(vg,0,sizeof(vg)); 44 if(dfs(i)) break; 45 int d=inf; 46 for(int j=0;j<m;j++) if(!vb[j]) d=min(d,slack[j]); 47 if(d==inf) return -1; 48 for(int j=0;j<n;j++) if(vg[j]) eg[j]-=d; 49 for(int j=0;j<m;j++) 50 if(vb[j]) eb[j]+=d; 51 else slack[j]-=d; 52 } 53 } 54 int ans=0; 55 for(int i=0;i<m;i++){ 56 if(mc[i]!=-1){ 57 if(c[mc[i]][i]!=-inf) ans+=c[mc[i]][i]; 58 else return -1; 59 } 60 } 61 return ans; 62 } 63 64 int main(){ 65 int u,v,w; 66 int kase=0; 67 while(scanf("%d%d%d",&n,&m,&r)!=EOF){ 68 for(int i=0;i<n;i++) 69 for(int j=0;j<m;j++) 70 c[i][j]=-inf; 71 for(int i=0;i<r;i++){ 72 scanf("%d%d%d",&u,&v,&w); 73 if(w>=0) c[u][v]=w; 74 } 75 printf("Case %d: %d\n",++kase,KM()); 76 } 77 }
slack
时间: 2024-10-12 03:04:19