One fihgt one HDU-2813 (最小权匹配)

题目链接

题意:

吕布的士兵和曹操对打,选取合适的对阵使吕布军队受伤最小

思路:

存负边,跑最小权匹配算法

我用scanf   Timi 了 2页,然后用 cin 关了输入输出流 A了 Debug一下午 真坑

AC代码:

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int maxn = 205;
const int INF = 0x3f3f3f3f;
vector< pair<int, int> > G[maxn * 2];
bool vis_X[maxn], vis_Y[maxn];
int ex_X[maxn], ex_Y[maxn];
int Match[maxn];
int Slack[maxn];

int N, M, K;
void init(){
    for(int i = 1; i <= N; ++i) {
        G[i].clear();
    }
}
bool Dfs(int x){
    vis_X[x] = 1;
    int v, c;
    for (int i = 0; i < G[x].size(); ++i) {
        v = G[x][i].first;
        c = G[x][i].second;
        if (vis_Y[v]) continue;
        int Tmp = ex_X[x] + ex_Y[v] - c;
        if (Tmp != 0) {
            Slack[v] = min (Slack[v], Tmp);
        } else {
            vis_Y[v] = 1;
            if (Match[v] == -1 || Dfs(Match[v])) {
                Match[v] = x;
                //cout << v << " " << Match[v] << " ---" << c <<endl; 
                return true;
            }
        }
    }
    return false;
}
int KM(){
    memset(Match, -1, sizeof(Match));
    memset(ex_Y, 0, sizeof(ex_Y));
    //for (int i = 1; i <= N; ++i) ex_X[i] = -INF;
    for (int i = 1; i <= N; ++i) {
        for(int j = 0; j < G[i].size(); ++j) {
            ex_X[i] = max (ex_X[i], G[i][j].second);
        }
    }
    for(int i = 1; i <= N; ++i){
        memset(Slack, INF, sizeof(Slack));
        while(1){
            memset(vis_X, 0, sizeof(vis_X));
            memset(vis_Y, 0, sizeof(vis_Y));
            if (Dfs(i)) break;
            int Tmp = INF;
            for(int j = 1; j <= M; ++j){
                if(vis_Y[j] == 0)
                    Tmp = min(Tmp, Slack[j]);
            }
            if(Tmp == INF) return -1;
            for (int j = 1; j <= N; ++j) {
                if (vis_X[j]) ex_X[j] -= Tmp;
            }
            for (int j = 1; j <= M; ++j) {
                if (vis_Y[j]) ex_Y[j] += Tmp;
                else Slack[j] -= Tmp;
            }
        }
    }
    int Ans = 0;
    for(int i = 1; i <= M; ++i){
        if(Match[i] != -1){
            for(int j = 0; j < G[Match[i]].size(); ++j){
                if (G[Match[i]][j].first == i){
                    Ans += G[Match[i]][j].second;
                    //cout << Match[i] << " " << i << " ---" << G[Match[i]][j].second << endl; 
                }
            }
        }
    }
    return -Ans;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    string s1, s2;
    int c;
    int L, R;
    while (cin >> N >> M >> K) {
        map<string, int> Lv, Cao;
        init();
        L = 1, R = 1;
        for (int i = 1; i <= K; ++i) {
            cin >> s1 >> s2 >> c;
            if(Lv[s1] == 0) Lv[s1] = L++;
            if(Cao[s2] == 0) Cao[s2] = R++;
            G[Lv[s1]].push_back(make_pair(Cao[s2], -c));
            //cout << "xian  " << Lv[s1] << "--" << Cao[s2] << " " << -c << endl;
        }
        cout << KM() << endl;  
    }
    return 0;
}

Slack数组可以不要 直接要个Slack  存最小降低期望就可以了

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int maxn = 205;
const int INF = 0x3f3f3f3f;
vector< pair<int, int> > G[maxn * 2];
bool vis_X[maxn], vis_Y[maxn];
int ex_X[maxn], ex_Y[maxn];
int Match[maxn];
int Slack;

int N, M, K;
void init(){
    for(int i = 1; i <= N; ++i) {
        G[i].clear();
    }
}
bool Dfs(int x){
    vis_X[x] = 1;
    int v, c;
    for (int i = 0; i < G[x].size(); ++i) {
        v = G[x][i].first;
        c = G[x][i].second;
        if (vis_Y[v]) continue;
        int Tmp = ex_X[x] + ex_Y[v] - c;
        if (Tmp != 0) {
            Slack = min (Slack, Tmp);
        } else {
            vis_Y[v] = 1;
            if (Match[v] == -1 || Dfs(Match[v])) {
                Match[v] = x;
                //cout << v << " " << Match[v] << " ---" << c <<endl; 
                return true;
            }
        }
    }
    return false;
}
int KM(){
    memset(Match, -1, sizeof(Match));
    memset(ex_Y, 0, sizeof(ex_Y));
    //for (int i = 1; i <= N; ++i) ex_X[i] = -INF;
    for (int i = 1; i <= N; ++i) {
        for(int j = 0; j < G[i].size(); ++j) {
            ex_X[i] = max (ex_X[i], G[i][j].second);
        }
    }
    for(int i = 1; i <= N; ++i){
    
        while(1){
        	Slack = INF;
            memset(vis_X, 0, sizeof(vis_X));
            memset(vis_Y, 0, sizeof(vis_Y));
            if (Dfs(i)) break;
    
            for (int j = 1; j <= N; ++j) {
                if (vis_X[j]) ex_X[j] -= Slack;
            }
            for (int j = 1; j <= M; ++j) {
                if (vis_Y[j]) ex_Y[j] += Slack;
            }
        }
    }
    int Ans = 0;
    for(int i = 1; i <= M; ++i){
        if(Match[i] != -1){
            for(int j = 0; j < G[Match[i]].size(); ++j){
                if (G[Match[i]][j].first == i){
                    Ans += G[Match[i]][j].second;
                    //cout << Match[i] << " " << i << " ---" << G[Match[i]][j].second << endl; 
                }
            }
        }
    }
    return -Ans;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    string s1, s2;
    int c;
    int L, R;
    while (cin >> N >> M >> K) {
        map<string, int> Lv, Cao;
        init();
        L = 1, R = 1;
        for (int i = 1; i <= K; ++i) {
            cin >> s1 >> s2 >> c;
            if(Lv[s1] == 0) Lv[s1] = L++;
            if(Cao[s2] == 0) Cao[s2] = R++;
            G[Lv[s1]].push_back(make_pair(Cao[s2], -c));
            //cout << "xian  " << Lv[s1] << "--" << Cao[s2] << " " << -c << endl;
        }
        cout << KM() << endl;  
    }
    return 0;
}
 
发布了199 篇原创文章 · 获赞 156 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/Harington/article/details/97274857
one
今日推荐