二分匹配_HDU_3081

来源:互联网 发布:淘宝客服分流时间设置 编辑:程序博客网 时间:2024/06/16 11:10

男女搭配,女生还可以跟闺蜜的可搭配的男生搭配,而且闺蜜还具有传递关系,问最后有多少种搭配方式。
首先,求搭配方式就是一种搭配成功,就把这个搭配的边删除,在搭配
然后就是传递之间的搭配,我是比较土的dfs出闺蜜圈,然后在搭上可以配对的

#include<iostream>#include<cstdio>#include<cstring>const int maxn = 105;using namespace std;int map[maxn][maxn],fd[maxn][maxn];int vis[maxn],par[maxn],link[maxn],vised[maxn];int n,m,f,tot;void init(){    int u,v;    memset(map, 0, sizeof(map));    memset(fd, 0, sizeof(fd));    scanf("%d%d%d",&n,&m,&f);    while(m--)    {        scanf("%d%d",&u,&v);        map[u][v] = 1;    }    while(f--)    {        scanf("%d%d",&u,&v);        fd[u][v] = fd[v][u] = 1;    }}void dfs(int x)//y是当前点{    vis[x] = 1;    par[tot++] = x;    for(int i = 1; i <= n; i++)    {        if(!vis[i]&&fd[x][i])        {            dfs(i);        }    }}int can(int x){    for(int i = 1; i <= n; i++)    {        if(!vised[i]&&map[x][i])        {            vised[i] = 1;            if(link[i]==-1 || can(link[i]))            {                link[i] = x;                return 1;            }        }    }    return 0;}int solve(){    int ret = 0;    memset(link, -1,sizeof(link));    for(int i = 1; i <= n; i++)    {        memset(vised, 0, sizeof(vised));        if(!can(i))            return 0;    }    return 1;}void addfriend()//闺蜜那你寻配偶{    tot = 0;    memset(vis, 0, sizeof(vis));    for(int i = 1; i <= n; i++)    {        if(!vis[i])        {            dfs(i);            for(int j = 0; j < tot; j++)            {                for(int k = 0; k < tot; k++)                {                    if(j != k)                    {                        for(int g = 1; g <= n; g++)                        {                            if(map[par[k]][g])                            {                                map[par[j]][g] = 1;                            }                        }                    }                }            }            tot = 0;        }    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int ans = 0;        init();        addfriend();        while(solve())        {            ans++;            for(int i = 1; i <= n; i++)            {                map[link[i]][i] = 0;            }        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击