随笔-38  评论-23  文章-0  trackbacks-0
二分图的最小权值匹配问题。。。直接用浙大模板水过..
#include<iostream>
#include
<string>
#include
<map>
#define MAXN 310
#define inf 1000000000
#define _clr(x) memset(x,0xff,sizeof(int)*n)
using namespace std;
int kuhn_munkras(int m,int n,int mat[][MAXN],int* match1,int* match2){
    
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;
}


int main()
{
    
int m,n,k,v;
    
char name1[20],name2[20];
    map
<string,int>::iterator it;
    
int mat[MAXN][MAXN];
    map
<string,int> name,mapname;
    
while(cin>>m>>n>>k)
    
{
        
int j=0,l1,l2,l=0;
        
for(int i=0;i<m;i++)
            
for(int j=0;j<n;j++)
                mat[i][j]
=-10000000;
        name.clear();
        
for(int i=0;i<k;i++)
        
{
            cin
>>name1>>name2>>v;
            
string name3(name1),name4(name2);
            it
=name.find(name3);
            
if(it==name.end())
            
{
                name[name3]
=j;
                l1
=j++;
            }

            
else
            
{
                l1
=it->second;
            }

            it
=mapname.find(name4);
            
if(it==mapname.end())
            
{
                mapname[name4]
=l;
                l2
=l++;
            }

            
else
            
{
                l2
=it->second;
            }

            mat[l1][l2]
=v*(-1);
        }

        
int match1[MAXN],match2[MAXN];
        cout
<<-1*kuhn_munkras(m,n,mat,match1,match2)<<endl;
    }

    
return 0;
}

posted on 2009-05-02 20:47 米游 阅读(377) 评论(0)  编辑 收藏 引用 所属分类: ACM

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理