二分图——匈牙利算法

匈牙利算法参考链接:

https://blog.csdn.net/sixdaycoder/article/details/47680831

https://www.renfei.org/blog/bipartite-matching.html

 

题目一:

hdu 1083

题意:

一共有N个学生跟P门课程,一个学生可以任意选一 门或多门课,问是否达成:

 1.每个学生选的都是不同的课(即不能有两个学生选同一门课)

 2.每门课都有一个代表(即P门课都被成功选过)

输入为:

第一行一个T代表T组数据

P N(P课程数, N学生数)

接着P行:

第几行代表第几门课程,首先是一个数字k代表对这门课程感兴趣的同学的个数,接下来是k个对这门课程感兴趣同学的编号。

 

题解:直接建个二分图搞定。

#include
#include
#include
#include
#include

using namespace std;

const int maxn=310;

vector G[maxn];

int match[maxn];
bool check[maxn];

bool dfs(int u)
{
    for(int i=0;i

 

题目二:

zoj 1654

参考链接:https://blog.csdn.net/wchhlbt/article/details/76687002

https://www.2cto.com/kf/201308/233630.html

题意:见链接。

#include
#include
#include

using namespace std;

const int maxn=51;
char op[maxn][maxn];

int x[maxn][maxn],y[maxn][maxn];

int maps[maxn*maxn][maxn*maxn];

bool vis[maxn*maxn];
int cx[maxn*maxn],cy[maxn*maxn];

int xpiece,ypiece;

int dfs(int u)
{
    for(int v=1;v<=ypiece;v++)
    {
        if(maps[u][v]&&!vis[v]){
            vis[v]=1;

            if(cy[v]==-1||dfs(cy[v]))
            {
                cy[v]=u;
                return 1;
            }
        }
    }
    return 0;
}

int hungarian()
{
    memset(cy,-1,sizeof(cy));

   int res=0;

    for(int i=1;i<=xpiece;i++)
    {
        memset(vis,0,sizeof(vis));
        res+=dfs(i);
    }
    return res;
}

int main()
{
    int ncase;

    scanf("%d",&ncase);
    int T=0;

    while(ncase--)
    {
        int m,n;
        scanf("%d%d",&m,&n);


        for(int i=0;i

 

 

你可能感兴趣的:(数据结构)