二分图最大匹配(邻接表法)

原创 2017年08月22日 21:25:45

二分图最大匹配(邻接表法)

题目链接:https://cn.vjudge.net/contest/181019#problem/F

题目大意:给你一个n*n的矩阵,问你能不能从这个矩阵的所有对角线上各取一个数,这2n-1个数各不相同,如果能,输出这些数,不能就输出NO,,,这些数的范围是1-10的9次方,,,

这题用二分图匹配做,将这些对角线当做男生,将这些对角线上的数当做女生,将这个数在这条对角线上当做关系,然后就是男生去找女生,要求的是找的最多的有多少男生,如果有2n-1个男生能匹配心仪的女生,就输出YES,否则输出NO,

这题最坑的地方就是,,这些数的范围太大,不能用二维的数组来存储他们之间的关系,所以要用到邻接表来存储,,,具体实现看代码

AC代码:

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <stack>
#include <cctype>
#include <set>
#include <ctype.h>
#include <string.h>
#define inf 999999999
#define eps 0.000001
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long ll;
const int maxn=300*300+10;
set<int>p[maxn];
vector<int>e[maxn];
map<int,int>q;
set<int>vis;//判断某个数是否已经用过
int ans[600+10];
int s[310][310];
int dfs(int x)
{
    for(int i=0;i<e[x].size();i++)
    {
        int t=e[x][i];
        if(!vis.count(t))
        {
            vis.insert(t);
            if(!q[t]||dfs(q[t]))
            {
                q[t]=x;//q[t]表示t这个数(t就相当于这个女生是否名花无主或者可以换个男生对象)是否有主了
                ans[x]=t;//有主了记录t这个数的主人是哪条对角线
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int n;
    //cin>>n;
    scanf("%d",&n);
    for(int i=0;i<maxn;i++)
        e[i].clear();
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            //cin>>s[i][j];
            scanf("%d",&s[i][j]);
            if(!p[n-j+i].count(s[i][j]))
            {
                p[n-j+i].insert(s[i][j]);
                e[n-j+i].push_back(s[i][j]);//排除一条对角线上相同的数,留下不同的数
            }
        }
    }
    int sum=0;
    q.clear();
    for(int i=1;i<=2*n-1;i++)
    {
        vis.clear();
        if(dfs(i))
            sum++;
    }
    if(sum!=2*n-1)
    {
        //cout<<"NO"<<endl;
        printf("NO\n");
    }
    else
    {
        printf("YES\n");
        for(int i=2*n-1;i>=1;i--)
        {
            if(i==1)
                printf("%d",ans[i]);
            else
                printf("%d ",ans[i]);
        }
        printf("\n");
    }
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

HDU 3729-I'm Telling the Truth-周赛4补题-二分图最大匹配-邻接表

题意:      新学期开学,老师想知道各个同学的分数,同学们不想把自己的真实分数告诉老师,只和老师说自己的排名在哪个范围内,有些同学和老师说的数据是不真实的,现在让你找到说的信息是真的同学的数目和序...

POJ-2446 邻接表+二分图匹配

在孔神的指导下做出了的。。太水了,邻接表都用不好。。。 #include #include #include #include #include #include #include #...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

HDU 1151 Air Raid 最小路径覆盖,二分图匹配匈牙利算法(邻接表存关系)处理有向图

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1151 Air Raid Time Limit: 2000/1000 MS (Java/Others)...

POJ 3041 最小点覆盖 二分图最大匹配(hungary邻接阵)

二分图由n行(A集)、n列(B集)组成,(x,y)有陨石等价于x∈A -> y∈b 有一条有向边。 消去x行等价于覆盖x这个点。问题转化为求这个二分图的最小点覆盖。 Asteroids ...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)