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

POJ - 2594 Treasure Exploration 二分图匹配 + floyd

时间:2015-06-06 22:08:32      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:在火星上有N个矿,有点矿之间存在着一条路,由于在火星比较特殊,该路变成了单向路,且机器人只能出现在这条路的两个端点,问最少需要派多少机器人,才能探清这些矿

解题思路:路可以拼接起来形成一条新的路,所以在所给的条件下还可以再扩展,用floyd将所有能连通的点找出来
接下来就是二分匹配的过程了,求出最大匹配数,在用n-最大匹配数就是答案了

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int N = 510;
int road[N][N], n, m;
int link[N], vis[N];
void floyd() {
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                if(road[i][k] && road[k][j])
                    road[i][j] = 1;
}

void init() {
    int x, y;
    memset(road, 0, sizeof(road));
    for(int i = 0; i < m; i++) {
        scanf("%d%d", &x, &y);
        road[x][y] = 1;
    }
    memset(link, 0, sizeof(link));  
    floyd();
}

bool dfs(int u) {
    for(int i = 1; i <= n; i++)
        if(road[u][i] && !vis[i]) {
            vis[i] = 1;
            if(!link[i] || dfs(link[i])) {
                link[i] = u;
                return true;
            }
        }
    return false;
}

void hungary() {
    int ans = 0;
    for(int i = 1; i <= n; i++) {
        memset(vis,0,sizeof(vis));
        if(dfs(i))
            ans++;
    }
    printf("%d\n", n - ans);
}

int main() {
    while(scanf("%d%d", &n, &m) != EOF && n + m) {
        init();
        hungary();
    }   
    return 0;
}

POJ - 2594 Treasure Exploration 二分图匹配 + floyd

标签:

原文地址:http://blog.csdn.net/l123012013048/article/details/46391493

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