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

来源:互联网 发布:摇号的软件 编辑:程序博客网 时间:2024/05/29 19:11

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

题目链接: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;}
原创粉丝点击