HDU 2255 KM模版题

来源:互联网 发布:知阅小说网_原创小说网 编辑:程序博客网 时间:2024/06/06 17:06

点击打开链接

题意:很明了

思路:KM模版题目,不多说测模版用的,而且好像用费用流会超时

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INF=0x3f3f3f3f3f3f3f3fll;const int maxn=310;int s[maxn][maxn],visx[maxn],visy[maxn],match[maxn];int lx[maxn],ly[maxn];int n,m;int hungarian(int x){    visx[x]=1;    for(int i=1;i<=m;i++){        if(!visy[i]&&lx[x]+ly[i]==s[x][i]){            visy[i]=1;            if(!match[i]||hungarian(match[i])){                match[i]=x;                return 1;            }        }    }    return 0;}int KM(){    int sum=0;    memset(lx,0,sizeof(lx));    memset(ly,0,sizeof(ly));    memset(match,0,sizeof(match));    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            lx[i]=max(lx[i],s[i][j]);    for(int i=1;i<=n;i++){        while(1){            memset(visx,0,sizeof(visx));            memset(visy,0,sizeof(visy));            if(hungarian(i))break;            else{                int temp=INF;                for(int j=1;j<=n;j++){                    if(visx[j]){                        for(int k=1;k<=m;k++)                        if(!visy[k])                        temp=min(temp,lx[j]+ly[k]-s[j][k]);                    }                }                if(temp==INF) return -1;                for(int j=1;j<=n;j++) if(visx[j]) lx[j]-=temp;                for(int j=1;j<=m;j++) if(visy[j]) ly[j]+=temp;            }        }    }    for(int i=1;i<=m;i++){        if(match[i]!=0){            if(s[match[i]][i]!=-INF) sum+=s[match[i]][i];            else return -1;        }    }    return sum;}int main(){    while(scanf("%d",&n)!=-1){        m=n;        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                scanf("%d",&s[i][j]);            }        }        int ans=KM();        printf("%d\n",ans);    }    return 0;}

1 0
原创粉丝点击