赤裸裸的带权最大匹配
- #include <iostream>
- #include <vector>
- using namespace std;
- #define MAXN 505
- #define inf 2000000000
- #define _clr(x) memset(x,0xff,sizeof(int)*n)
- int mat[MAXN][MAXN],n,m,match1[MAXN], match2[MAXN];
- bool map[MAXN][MAXN];
- int kuhn_munkras(int n, int m){
- int s[MAXN],t[MAXN],l1[MAXN],l2[MAXN],p,q,ret=0,i,j,k;
- for (i=0;i<m;i++)
- for (l1[i]=-inf,j=0;j<n;j++)
- l1[i]=mat[i][j]>l1[i]?mat[i][j]:l1[i];
- for (i=0;i<n;l2[i++]=0);
- for (_clr(match1),_clr(match2),i=0;i<m;i++){
- for (_clr(t),s[p=q=0]=i;p<=q&&match1[i]<0;p++)
- for (k=s[p],j=0;j<n&&match1[i]<0;j++)
- if (l1[k]+l2[j]==mat[k][j]&&t[j]<0){
- s[++q]=match2[j],t[j]=k;
- if (s[q]<0)
- for (p=j;p>=0;j=p)
- match2[j]=k=t[j],p=match1[k],match1[k]=j;
- }
- if (match1[i]<0){
- for (i--,p=inf,k=0;k<=q;k++)
- for (j=0;j<n;j++)
- if (t[j]<0&&l1[s[k]]+l2[j]-mat[s[k]][j]<p)
- p=l1[s[k]]+l2[j]-mat[s[k]][j];
- for (j=0;j<n;l2[j]+=t[j]<0?0:p,j++);
- for (k=0;k<=q;l1[s[k++]]-=p);
- }
- }
- for (i=0;i<m;i++)
- ret+=mat[i][match1[i]];
- return ret;
- }
- bool DEBUG=false;
- int main()
- {
- int t,x,y,len,i,j,k,ans,id=0;
- while(scanf("%d%d%d",&n,&m,&k)!=EOF)
- {
- for(i=0;i<n;i++)for(j=0;j<m;j++)mat[i][j]=-inf;
- memset(map,false,sizeof(map));
- while(k--)
- {
- scanf("%d%d%d",&x,&y,&len);
- if(len<0)continue;
- mat[x][y]=len;
- map[x][y]=true;
- }
- printf("Case %d: ",++id);
- if(n>m)
- {
- printf("-1/n");
- continue;
- }
- ans=kuhn_munkras(m,n);
- for(i=0;i<n;i++)if(!map[i][match1[i]])break;
- printf("%d/n",i==n?ans:-1);
- }
- return 0;
- }