首页 > 其他分享 >HDU - 3081 Marriage Match II(二分图最大匹配 + 并查集)

HDU - 3081 Marriage Match II(二分图最大匹配 + 并查集)

时间:2023-04-07 11:06:52浏览次数:44  
标签:HDU 匹配 游戏 int 查集 father II 男女 配对


题目大意:有n个男生n个女生,现在要求将所有的男女配对,所有的男女都配对的话,算该轮游戏结束了。接着另一轮游戏开始,还是男女配对,但是配对的男女不能是之前配对过的。
问这游戏能玩多少轮
男女能配对的条件如下
1.男女未曾吵架过。
2.如果两个女的是朋友,那么另一个女的男朋友可以和该女的配对

解题思路:并查集解决朋友之间的关系,找到能配对的所有情况
接着二分图匹配,找到一个完美匹配算玩了一轮游戏,接着将这完美匹配的边删掉,继续进行匹配
如果无法完美匹配了,表示游戏结束了

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1010
int g[N][N], link[N], vis[N], father[N];
int n, m, f;

int find(int x) {
    return x == father[x] ? x : father[x] = find(father[x]);
}

void init() {
    scanf("%d%d%d", &n, &m, &f);
    memset(g, 0, sizeof(g));
    for (int i = 1; i <= n; i++)
        father[i] = i;

    int x, y;
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &x, &y);
        g[x][y] = 1;
    }

    for (int i = 0; i < f; i++) {
        scanf("%d%d", &x, &y);
        father[find(x)] = find(y);
    }

    for (int i = 1; i <= n; i++) {
        int t = find(i);

        for (int j = 1; j <= n; j++) {
            if (i != j && t == find(j)) {
                for (int k = 1; k <= n; k++)
                    if (g[j][k])
                        g[i][k] = 1;
            }
        }
    }
}

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

void solve() {
    int ans = 0;
    while (1) {
        memset(link, 0, sizeof(link));
        int cnt = 0;
        for (int i = 1; i <= n; i++) {
            memset(vis, 0, sizeof(vis));
            if (dfs(i))
                cnt++;
        }
        if (cnt == n) {
            ans++;
            for (int i = 1; i <= n; i++)
                g[link[i]][i] = 0;
        }
        else
            break;
    }
    printf("%d\n", ans);
}

int main() {
    int test;
    scanf("%d", &test);
    while (test--) {
        init();
        solve();
    }
    return 0;
}


标签:HDU,匹配,游戏,int,查集,father,II,男女,配对
From: https://blog.51cto.com/u_10970600/6175569

相关文章

  • HDU - 3715 Go Deeper (二分 + 2-SAT)
    题目大意:给出一个递归函数,问这个递归函数最多能递归几层解题思路:二分枚举递归层数,然后依此建边如果给出的c[i]为0时,那么x[a[i]]和x[b[i]]中的其中一个要为真,连边即为!a[i]->b[i],!b[i]->a[i]如果给出的c[i]为1时,那么x[a[i]]和x[b[i]]两个要么都为真,要么都为假,连边即为a[i]->b[i......
  • HDU - 1317 XYZZY (floyd + 最长路)
    题目大意:有一种游戏,游戏里面有N个房间,每个房间有相应的能量值,走入该房间就可以得到相应的能量值现在你要从房间1出发,走到房间N,如果中途能量耗尽了,就表示输了,反之,则为赢解题思路:首先得判断一下能不能到达N,这可以用Floyd去判断如果能直接走到N的话,就算赢,否则判断一下,看是否有正环......
  • HDU 5479 Scaena Felix(DP)
    题目大意:给出一系列的由’(‘和’)’组成的字符串,现有一种操作,可以将括号的方向变反,但需要花费1现在问,需要花费多少的代价才能使该字符串的任意一个连续子串都不存在”()”的配对解题思路:用dp[i][0]表示第i个位置变成’(‘的代价,dp[i][1]表示第i个位置变成’)’的代价如果当前......
  • asciinema 方便的终端录屏方案
    asciinema方便的终端录屏方案,我们可以直接使用cli工具就可以方便的进行终端录制了,然后可以自己提供一份website基于官方提供的asciinema-player进行播放参考玩法  简单说明:我们可以基于s3以及asciinema提供的工具自己包装一个ui当然也可以直接使用官方提供的asci......
  • 142. 环形链表 II
     解法一:①首先判断是否有环,若无环,则快指针或其下一指针指向空;若有环,则从快慢指针相遇的位置继续出发,直到再次相遇,遍历次数即为环长len。②两指针从头结点重新开始,让其中一指针先出发len步,而后另一指针再出发,相遇节点即为环起点。/***Definitionforsingly-linkedlist.*......
  • 剑指 Offer 14- II. 剪绳子 II
    题目链接:剑指Offer14-II.剪绳子II方法:数论解题思路将\(n\)分为\(m\)个数的和,使得这\(m\)个数的乘积最大,那么应该将\(m\)个数分为\(2\)和\(3\)的组合,尽可能为\(3\)。注意大数越界问题。代码classSolution{public:intcuttingRope(intn){......
  • 算法题-朋友圈-并查集
    朋友圈现在有105个用户,编号为1-105,现在已知有m对关系,每一对关系给你两个数x和y,代表编号为x的用户和编号为y的用户是在一个圈子中,例如:A和B在一个圈子中,B和C在一个圈子中,那么A,B,C就在一个圈子中。现在想知道最多的一个圈子内有多少个用户。数据范围:......
  • 并查集
    CF371DVessels点击查看题目点击查看思路定义一个权值并查集,权值保存这个集合还可以存下多少水。如果这个集合可以存放的水已经小于要装入的水,就将这个集合与下一个集合合并。否则,直接把这个集合可以存放的水减去要装入的水的体积。点击查看代码#include<bits/stdc+......
  • 树:剑指 Offer 68 - II. 二叉树的最近公共祖先
    题目描述:给定一个二叉树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树T的两个结点p、q,最近公共祖先表示为一个结点x,满足x是p、q的祖先且x的深度尽可能大(一个节点也可以是它自己的祖先)。” 例如,给定如下二叉树: root= ......
  • Rider-调试并配置本地IIS
    项目部署到IISIIS:新建Web站点,路径指向Web应用程序根目录,端口默认80端口;应用程序池:".NetCLR版本"选择.NetCLR版本v4.0.30319,托管管道模式选择"集成"。  Web项目配置在Rider中选中Web项目,输入F4,打开csproj文件,添加如下配置。1<WebProjectProperties>2<U......