二分图最大匹配 (hdu1281、1528)

(hdu1281)棋盘游戏

题意:棋盘中一些格子可以放棋子,但要求棋子不能同行也不能同列。有一些格子若不放棋子,则最大匹配数目减少,则这个格子就是“重要点”。

二分图的匹配:给定一个二分图G,M为G边集的一个子集,如果M满足当中的任意两条边都不依附于同一个顶点,则称M是一个匹配。

#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"algorithm"
using namespace std;
#define N 105
int g[N][N];
int mark[N],link[N],n,m;
int find(int k)
{
    int i;
    for(i=1;i<=m;i++)
    {
        if(g[k][i]&&!mark[i])
        {
            mark[i]=1;
            if(link[i]==-1||find(link[i]))
            {
                link[i]=k;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int i,j,u,v,k,T=1;
    while(scanf("%d%d%d",&n,&m,&k)!=-1)
    {
        memset(link,-1,sizeof(link));
        memset(g,0,sizeof(g));
        while(k--)
        {
            scanf("%d%d",&u,&v);
            g[u][v]=1;
        }
        int ans=0,cnt=0;
        for(i=1;i<=n;i++)
        {
            memset(mark,0,sizeof(mark));
            ans+=find(i);
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(g[i][j])
                {
                    g[i][j]=0;
                    memset(link,-1,sizeof(link));
                    int t=0;
                    for(k=1;k<=n;k++)
                    {
                        memset(mark,0,sizeof(mark));
                        t+=find(k);
                    }
                    g[i][j]=1;
                    if(t<ans)
                        cnt++;
                }
            }
        }
        printf("Board %d have %d important blanks for %d chessmen.\n",T++,cnt,ans);
    }
    return 0;
}

(hdu1528)Card Game Cheater

题意:相当于田忌赛马的游戏,只不过换成扑克牌。比较点数大小,点数相同按花色分大小,红桃》黑桃》方块》梅花。

思路:把每张牌和一个数字映射起来,使得映射后的大小和牌中一样。然后建图,把 Eve的牌大于Adam的牌建一条边。

然后,求出最大匹配就OK了。

#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define N 60
int a[N],b[N],g[N][N];
int mark[N],link[N];
int getch(char*s)    //把牌数转化为数字
{
    int t;
    switch(s[0])
    {
        case 'T':t=9;break;
        case 'J':t=10;break;
        case 'Q':t=11;break;
        case 'K':t=12;break;
        case 'A':t=13;break;
        default :t=s[0]-'0'-1;break;
    }
    t*=4;
    if(s[1]=='S')
        t-=1;
    else if(s[1]=='D')
        t-=2;
    else if(s[1]=='C')
        t-=3;
    //printf("%d\n",t);
    return t;
}
int find(int k)       //匈牙利算法求最大匹配数目
{
    int i;
    for(i=1;i<N;i++)
    {
        if(g[k][i]&&!mark[i])
        {
            mark[i]=1;
            if(link[i]==-1||find(link[i]))
            {
                link[i]=k;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int i,j,t,n,n1,n2,T;
    char s[5];
    scanf("%d",&T);
    while(T--)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(g,0,sizeof(g));
        scanf("%d",&n);
        n1=n2=0;
        for(i=0;i<n;i++)
        {
            scanf("%s",s);
            t=getch(s);
            a[n1++]=t;
        }
        for(i=0;i<n;i++)
        {
            scanf("%s",s);
            t=getch(s);
            b[n2++]=t;
        }
        for(i=0;i<n1;i++)      //建图
        {
            for(j=0;j<n2;j++)
            {
                if(a[i]<b[j])
                    g[b[j]][a[i]]=1;
            }
        }
        int ans=0;
        memset(link,-1,sizeof(link));
        for(i=1;i<N;i++)
        {
            memset(mark,0,sizeof(mark));
            ans+=find(i);
        }
        printf("%d\n",ans);
    }
    return 0;
}

二分图最大匹配 (hdu1281、1528)

时间: 2024-11-09 01:29:18

二分图最大匹配 (hdu1281、1528)的相关文章

HDU 1528 (二分图最大匹配 + 最小覆盖, 14.07.17)

Problem Description Adam and Eve play a card game using a regular deck of 52 cards. The rules are simple. The players sit on opposite sides of a table, facing each other. Each player gets k cards from the deck and, after looking at them, places the c

匈牙利算法dfs模板 [二分图][二分图最大匹配]

最近学了二分图最大匹配,bfs模板却死活打不出来?我可能学了假的bfs 于是用到了dfs模板 寻找二分图最大匹配的算法是匈牙利算法 匈牙利算法的主要程序是寻找增广路 寻找增光路是过程是:从一个未经配对的点出发,历经未配边.匹配边.未配边.匹配边.未配边....最终到达一个未配点的过程,只要把路径中的未配边和匹配边的“身份”对调,匹配就加一了.这就是一个寻找增广路的过程,通过不断寻找增广路,可以找到最大的匹配. 1 #include<cstdio> 2 #include<cstring&g

图论——LCA、强联通分量、桥、割顶、二分图最大匹配、网络流

A: 交通运输线 时间限制: 5 Sec  内存限制: 128 MB 题目描述 战后有很多城市被严重破坏,我们需要重建城市.然而,有些建设材料只能在某些地方产生.因此,我们必须通过城市交通,来运送这些材料的城市.由于大部分道路已经在战争期间完全遭到破坏,可能有两个城市之间没有道路.当然在运输线中,更不可能存在圈. 现在,你的任务来了.给你战后的道路情况,我们想知道,两个城市之间是否存在道路,如果存在,输出这两个城市之间的最短路径长度. 输入 第一行一个整数Case(Case<=10)表示测试数据

POJ 2226二分图最大匹配

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法. #include<stdio.h> #include<string.h> #include<stdlib.h> int n1,n2; char map[1005][1005]; //数组开大点 int mapx[1005][1005],mapy[1005]

【Codevs1922】骑士共存问题(最小割,二分图最大匹配)

题意: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入. 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击. n<=200,m<=n^2 思路:经典的二分图最大匹配问题,采用黑白点染色的思想. 如果按照相邻点黑白不同染色,可以发现每次跳到的点必定与现在所在点不同色,二分图最大匹配即可. 这里用最小割来解决,因为不能允许任何黑白点之间的任何一条边有流量,符合最小割的思想. 1

POJ2239 Selecting Courses(二分图最大匹配)

题目链接 N节课,每节课在一个星期中的某一节,求最多能选几节课 好吧,想了半天没想出来,最后看了题解是二分图最大匹配,好弱 建图: 每节课 与 时间有一条边 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #include <vector> 7 using namespa

二分图最大匹配总结

hdoj1528 二分匹配模版: 代码: 1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 #include<math.h> 6 using namespace std; 7 #define N 220 8 9 int n, maps[N][N], vis[N], used[N]; 10 11 struct node 12 {

POJ - 1422 Air Raid 二分图最大匹配

题目大意:有n个点,m条单向线段.现在问要从几个点出发才能遍历到所有的点 解题思路:二分图最大匹配,只要一条匹配,就表示两个点联通,两个点联通只需要选取其中一个点即可,所以有多少条匹配,就可以减去多少个点 #include<cstdio> #include<cstring> using namespace std; const int N = 130; int g[N][N], vis[N], link[N]; int n, m; void init() { memset(g, 0

&quot;《算法导论》之‘图’&quot;:不带权二分图最大匹配(匈牙利算法)

博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利算法 1. 前言 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图.准确地说:把一个图的顶点划分为两个不相交集 U 和V ,使得每一条边都分别连接U.V中的顶点.如果存在这样的划分,则此图为一个二分图.二分图的一个等价定义是:不含有「含奇数条边的环」的图.