码迷,mamicode.com
首页 > 其他好文 > 详细

uva11045

时间:2016-12-07 02:20:15      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:节点   二分图匹配   解题思路   bre   ace   efi   net   型号   容量   

题目链接请戳 这里

 

解题思路:

二分图匹配用求最大流EK算法解决

可以把每件衣服都表示成一个节点,每当一个人可以和某种衣服匹配则与这种型号的所有衣服有容量为1的通道。

 

代码

#include<stdio.h>
#include<string.h>
#include<queue>
#define N 1200
#define INF 1e9
using namespace std;

int Cap[N][N], Flow[N][N];
int a[N], Pre[N]; 
int n, m;

//对衣服编码
int code(char ss[])
{
    int step = n / 6;
    if (strcmp(ss, "XXL") == 0) { return 1; }
    else if (strcmp(ss, "XL") == 0) { return step + 1; }
    else if (strcmp(ss, "L") == 0) { return 2 * step + 1; }
    else if (strcmp(ss, "M") == 0) { return 3 * step + 1; }
    else if (strcmp(ss, "S") == 0) { return 4 * step + 1; }
    else if (strcmp(ss, "XS") == 0) { return 5 * step + 1; }
}

int EK(int s, int t)
{
    queue<int> q;
    memset(Flow, 0, sizeof(Flow));
    int f = 0;
    while (1) {
        memset(a, 0, sizeof(a));
        a[s] = INF;
        q.push(s);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int v = s; v <= t; v++) if (!a[v] && Cap[u][v] > Flow[u][v]) {
                Pre[v] = u; q.push(v);
                a[v] = min(a[u], Cap[u][v] - Flow[u][v]);
            }
        }
        if (a[t] == 0) break;
        for (int u = t; u != s; u = Pre[u]) {
            Flow[Pre[u]][u] += a[t];
            Flow[u][Pre[u]] -= a[t];
        }
        f += a[t];
    }
    return f;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--) {
        memset(Cap, 0, sizeof(Cap));
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++) {
            char s1[10], s2[10];
            scanf("%s%s", s1, s2);
            int n1 = code(s1);
            int n2 = code(s2);
            for (int j = 0; j < n / 6; j++) { 
                Cap[i][m + n1 + j] = 1;
                Cap[i][m + n2 + j] = 1;
            }
        }

        //处理超级汇点和超级聚点
        for (int i = 1; i <= m; i++) Cap[0][i] = 1;
        for (int i = 1; i <= n; i++) Cap[m + i][n + m + 1] = 1;
        
        //最大流的结果就是最多能匹配的人数
        int res = EK(0, n + m + 1);
        if (res == m) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}    

 

uva11045

标签:节点   二分图匹配   解题思路   bre   ace   efi   net   型号   容量   

原文地址:http://www.cnblogs.com/ZengWangli/p/6139640.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!