1. 程式人生 > >51nod 2006 飛行員配對(二分圖最大匹配) 匈牙利匹配

51nod 2006 飛行員配對(二分圖最大匹配) 匈牙利匹配

u+ nco 如果 for 不存在 模板題 空間限制 收藏 輸入

2006 飛行員配對(二分圖最大匹配)技術分享 題目來源: 網絡流24題 基準時間限制:1 秒 空間限制:131072 KB 分值: 0 難度:基礎題 技術分享 收藏 技術分享 關註

第二次世界大戰時期,英國皇家空軍從淪陷國征募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的2名飛行員,其中1名是英國飛行員,另1名是外籍飛行員。在眾多的飛行員中,每一名外籍飛行員都可以與其他若幹名英國飛行員很好地配合。如何選擇配對飛行的飛行員才能使一次派出最多的飛機。對於給定的外籍飛行員與英國飛行員的配合情況,試設計一個算法找出最佳飛行員配對方案,使皇家空 軍一次能派出最多的飛機 。對於給定的外籍飛行員與英國飛行員的配合情況,編程找出一個最佳飛行員配對方案, 使皇家空軍一次能派出最多的飛機。

Input
第1行有2個正整數 m 和 n。n 是皇家空軍的飛行 員總數(n<100);m 是外籍飛行員數。外籍飛行員編號為 1~m;英國飛行員編號為 m+1~n。接下來每行有 2 個正整數 i 和 j,表示外籍飛行員 i 可以和英國飛行員 j 配合。輸入最後以 2 個-1 結束。
Output
第 1 行是最佳飛行 員配對方案一次能派出的最多的飛機數 M。如果所求的最佳飛行員配對方案不存在,則輸出‘No Solution!’。
Input示例
5 10
1 7
1 8
2 6
2 9
2 10
3 7
3 8
4 7
4 8
5 10
-1 -1
Output示例
4


模板題
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <iomanip>
#include <math.h>
#include <map>
using namespace std;
#define FIN     freopen("input.txt","r",stdin);
#define FOUT    freopen("output.txt","w",stdout);
#define INF     0x3f3f3f3f
#define INFLL   0x3f3f3f3f3f3f3f
#define lson    l,m,rt<<1
#define rson    m+1,r,rt<<1|1
typedef long long LL;
typedef pair<int, int> PII;
using namespace std;

/*復雜度O(VE)
最小點覆蓋=最大匹配數
最小邊覆蓋=左右點數-最大匹配數
最小路徑覆蓋=點數-最大匹配數
最大獨立集=點數-最大匹配數
*/

const int MX = 205;

struct Edge {
    int v, nxt;
}E[MX];

int Head[MX], tot;
int match[MX];
bool vis[MX];

void edge_init() {
    memset(Head, -1, sizeof(Head));
    memset(match, 0, sizeof(match));
    tot = 0;
}

void edge_add(int u, int v) {
    E[tot].v = v;
    E[tot].nxt = Head[u];
    Head[u] = tot++;
}

bool DFS(int u) {
    for(int i = Head[u]; ~i; i = E[i].nxt) {
        int v = E[i].v;
        if(!vis[v]) {
            vis[v] = 1;
            if(match[v] == -1 || DFS(match[v])) {
                //如果v已經被匹配了,且被匹配的點不是
                //當前點u,那麽就去修改這個match[v],如果修改成功了,那麽就可以返回1
                match[v] = u;
                return 1;
            }
        }
    }
    return 0;
}
int BM(int n) {
    int res = 0;
    memset(match, -1, sizeof(match));
    for(int u = 1; u <= n; u++) {
        memset(vis, 0, sizeof(vis));
        if(DFS(u)) res++;//找與u匹配的點v,如果找到了答案就+1
    }
    return res;
}

int main() {
    //FIN
    int n, m;
    while(~scanf("%d%d", &m, &n)) {
         int st, ed;
         edge_init();
         while(~scanf("%d%d", &st, &ed)) {
            if(st == -1 && ed == -1) break;
            edge_add(st, ed);
         }
         printf("%d\n", BM(m));


    }
    return 0;
}

  

51nod 2006 飛行員配對(二分圖最大匹配) 匈牙利匹配