HDU 2255 奔小康赚大钱(TEST 11.01)待解决

HDU 2255 奔小康赚大钱(TEST<25> 11.01)

解题思路

还是一脸懵逼 可能有些知识储备不够,再看看情况吧 资源贴下
CSDN1(O n4)
CSDN2 (O n3)
哔哩哔哩(很水 讲的啥呀…)
蓝皮书 P349

AC 代码如下

CSDN 1

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 305;
int match[N], vx[N], vy[N], lx[N], ly[N], wight[N][N];
int n, m, low; int dfs(int x);
const int inf = 0x3f3f3f;
 int dfs(int x) { 
     vx[x]=1;     
     for(int i=1;i<=n;i++) {         
         if(vy[i]) continue;            
         int t=lx[x]+ly[i]-wight[x][i];         
         if(t==0){             
         vy[i]=1;             
             if(match[i]==0||dfs(match[i])){               
                match[i]=x;                 
                return 1;            
             }        
         }         
         else if(low>t)  low=t;            
     }     
     return 0;
}
int main() {     
    while(scanf("%d", &n)!=EOF){ 
        memset(wight,0,sizeof(wight));
        memset(match,0,sizeof(match));         
        memset(lx,0,sizeof(lx));         
        memset(ly,0,sizeof(ly));         
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){                
             scanf("%d", &wight[i][j]);                 
             lx[i]=max(lx[i],wight[i][j]);             
             }         
        }         
        for(int i=1;i<=n;i++){             
             while(1){                 
                memset(vx,0,sizeof(vx));                 
                memset(vy,0,sizeof(vy));                
                low=inf;                 
               if(dfs(i)){                    
                break;               
                }                
                else{
                   for(int i=1;i<=n;i++){ 
                        if(vx[i])  lx[i]-=low;                       
                        if(vy[i])  ly[i]+=low;               
                  }                 
               }             
            }         
         }         
         int sum=0;         
         for(int i=1;i<=n;i++){             
         sum+=wight[match[i]][i]; 
                 }         
             printf("%d\n",sum);     
    }     
         return 0; 
 } 

CSDN 2

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 505
#define inf 0x3f3f3f3f
typedef long long ll;
int g[maxn][maxn];
int link[maxn],lx[maxn],ly[maxn],slack[maxn];
bool s[maxn],t[maxn];
int n;
bool dfs(int i){
    s[i]=1;
    for(int j=1;j<=n;j++){
        if(!t[j]){
            int temp=lx[i]+ly[j]-g[i][j];
            if(temp==0){
                t[j]=1;
                if(link[j]==-1||dfs(link[j])){
                    link[j]=i;
                    return true;
                }
            }
            else{
                slack[j]=min(temp,slack[j]);    //这里的slack保证了是s[]和!t[]的
            }
        }
    }
    return false;
}
void update(){
    int a=inf;
    for(int i=1;i<=n;i++){
        if(!t[i])a=min(a,slack[i]);
    }
    for(int i=1;i<=n;i++){
        if(s[i])lx[i]-=a;
        if(t[i])ly[i]+=a;
    }
}
int km(){
    for(int i=1;i<=n;i++){
        lx[i]=ly[i]=0;link[i]=-1;
        for(int j=1;j<=n;j++){
            lx[i]=max(lx[i],g[i][j]);
        }
    }
    for(int i=1;i<=n;i++){
        memset(slack,inf,sizeof slack);
        while(true){
            for(int j=1;j<=n;j++)s[j]=t[j]=0;
            if(dfs(i))break;
            else update();
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        if(link[i]!=-1)ans+=g[link[i]][i];    //因为权值是从左到右的,而link记录的是i的匹配边。
    }
    return ans;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&g[i][j]);
            }
        }
        int res=km();
        printf("%d\n",res);
    }
}
发布了55 篇原创文章 · 获赞 1 · 访问量 978

猜你喜欢

转载自blog.csdn.net/weixin_43556527/article/details/103075264