hdu3277marriagematchiii(并查集+二分答案+最大流sap)拆点,经典

yutingliuyl yutingliuyl     2022-09-16     230

关键词:

Marriage Match III

Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1581    Accepted Submission(s): 464


Problem Description
Presumably, you all have known the question of stable marriage match. A girl will choose a boy; it is similar as the ever game of play-house . What a happy time as so many friends play together. And it is normal that a fight or a quarrel breaks out, but we will still play together after that, because we are kids.

Now, there are 2n kids, n boys numbered from 1 to n, and n girls numbered from 1 to n. As you know, ladies first. So, every girl can choose a boy first, with whom she has not quarreled, to make up a family. Besides, the girl X can also choose boy Z to be her boyfriend when her friend, girl Y has not quarreled with him. Furthermore, the friendship is mutual, which means a and c are friends provided that a and b are friends and b and c are friend.

Once every girl finds their boyfriends they will start a new round of this game—marriage match. At the end of each round, every girl will start to find a new boyfriend, who she has not chosen before. So the game goes on and on. On the other hand, in order to play more times of marriage match, every girl can accept any K boys. If a girl chooses a boy, the boy must accept her unconditionally whether they had quarreled before or not.

Now, here is the question for you, how many rounds can these 2n kids totally play this game?
 

Input
There are several test cases. First is an integer T, means the number of test cases.
Each test case starts with three integer n, m, K and f in a line (3<=n<=250, 0<m<n*n, 0<=f<n). n means there are 2*n children, n girls(number from 1 to n) and n boys(number from 1 to n).
Then m lines follow. Each line contains two numbers a and b, means girl a and boy b had never quarreled with each other.
Then f lines follow. Each line contains two numbers c and d, means girl c and girl d are good friends.
 

Output
For each case, output a number in one line. The maximal number of Marriage Match the children can play.
 

Sample Input
1 4 5 1 2 1 1 2 3 3 2 4 2 4 4 1 4 2 3
 

Sample Output
3
 

Author
starvae
 

Source
题意:共同拥有2*n个人。一半女一半男,女与男有m个关系。表示能够成为一对,接下来 f 对女的与女的  的朋友关系,假设a与b是朋友。那么表示a女与b女的相连男性也能够成为一对,相同b也与a的相连男性可成为一对,女的之间的朋友关系能够传递。且每一个女性能够再随意选择K人。

一组配对情况为全部的女性都有一个与之配对的男性(一对一的关系)。假设还有其它组配对情况,那么全部的女性配对不能够再与原来的男性配成对。问最多有多少组配对情况。


 这题和HDU3081 非常类似。

可是由于能够任意选择K个人。

所以要将女孩拆成两个点。

将每一个女孩u分为u1,u2。若u喜欢v则加一条u1到v的边 否则加一条u2到v的边。令加u1到u2的容量为k的边;

这个拆点的想法很巧妙。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define captype int

const int MAXN = 100010;   //点的总数
const int MAXM = 4000100;    //边的总数
const int INF = 1<<30;
struct EDG{
    int to,next;
    captype cap,flow;
}edg[MAXM];
int eid,head[MAXN];
int gap[MAXN];
int dis[MAXN];
int cur[MAXN];
int pre[MAXN];

void init(){
    eid=0;
    memset(head,-1,sizeof(head));
}
void addEdg(int u,int v,captype c,captype rc=0){
    edg[eid].to=v; edg[eid].next=head[u];
    edg[eid].cap=c; edg[eid].flow=0; head[u]=eid++;

    edg[eid].to=u; edg[eid].next=head[v];
    edg[eid].cap=rc; edg[eid].flow=0; head[v]=eid++;
}
captype maxFlow_sap(int s,int t,int n){
    memset(gap,0,sizeof(gap));
    memset(dis,0,sizeof(dis));
    memcpy(cur,head,sizeof(head));
    pre[s]=-1;
    gap[0]=n;

    captype ans=0;
    int u=s;
    while(dis[s]<n){
        if(u==t){
            captype mint=INF;
            int id;
            for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to])
            if(mint>edg[i].cap-edg[i].flow){
                mint=edg[i].cap-edg[i].flow;
                id=i;
            }
            for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to]){
                edg[i].flow+=mint;
                edg[i^1].flow-=mint;
            }
            ans+=mint;
            u=edg[id^1].to;
            continue;
        }
        bool flag=0;
        for(int i=cur[u]; i!=-1; i=edg[i].next)
        if(edg[i].cap>edg[i].flow&&dis[u]==dis[edg[i].to]+1){
            cur[u]=pre[edg[i].to]=i;
            flag=true;
            break;
        }
        if(flag){
            u=edg[cur[u]].to;
            continue;
        }
        int minh=n;
        for(int i=head[u]; i!=-1; i=edg[i].next)
        if(edg[i].cap>edg[i].flow && minh>dis[edg[i].to]){
            cur[u]=i; minh=dis[edg[i].to];
        }
        gap[dis[u]]--;
        if(!gap[dis[u]]) return ans;
        dis[u]=minh+1;
        gap[dis[u]]++;
        if(u!=s)
         u=edg[pre[u]^1].to;
    }
    return ans;
}

int fath[MAXN];
int findroot(int x){
    if(x!=fath[x])
     fath[x]=findroot(fath[x]);
     return fath[x];
}
void setroot(int x,int y){
    x=findroot(x);
    y=findroot(y);
    fath[x]=y;
}
void rebuildMap(int mapt[255][255],int n){//处理朋友之间的关系
    int mp[255][255]={0};
    for(int i=1; i<=n; i++)
    fath[i]=findroot(i);
    for(int i=1; i<=n; i++){
        int j=fath[i];
        for(int e=1; e<=n; e++)
        mp[j][e]|=mapt[i][e];
    }
    for(int i=1; i<=n; i++){
        int j=fath[i];
        for(int e=1; e<=n; e++)
        mapt[i][e]=mp[j][e];
    }
}
int main()
{
    int T,n,m,k,f,mapt[255][255];
    int u,v;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d%d",&n,&m,&k,&f);

        init();
        memset(mapt,0,sizeof(mapt));
        for(int i=1; i<=n; i++)
            fath[i]=i;

        while(m--){
            scanf("%d%d",&u,&v);
            mapt[u][v]=1;
        }
        while(f--){
            scanf("%d%d",&u,&v);
            setroot(u,v);
        }
        rebuildMap(mapt,n);

        int s=0, t=3*n+1;
        for(int i=1; i<=n; i++){
            addEdg(s,i,0);
            addEdg(i,i+n,k);
            for(int j=1; j<=n; j++)
            if(mapt[i][j])
                addEdg(i,j+2*n,1);
            else
                addEdg(i+n,j+2*n,1);

            addEdg(i+2*n,t,0);
        }
        
        int ans=0 , l=0 , r=n ,mid;
        while(l<=r){
            mid=(l+r)>>1;
            
            for(int i=0; i<eid; i++)
                edg[i].flow=0;
            for(int i=head[s]; i!=-1; i=edg[i].next)
                edg[i].cap=mid;
            for(int i=head[t]; i!=-1; i=edg[i].next)
                edg[i^1].cap=mid;
                
            if(n*mid==maxFlow_sap(s,t,t+1))
                ans=mid,l=mid+1;
            else
                r=mid-1;
        }
        
        printf("%d
",ans);
    }
}


[poj3277]cityhorizon

[POJ3277]CityHorizon试题描述FarmerJohnhastakenhiscowsonatriptothecity!Asthesunsets,thecowsgazeatthecityhorizonandobservethebeautifulsilhouettesformedbytherectangularbuildings.Theentirehorizonisrepresented 查看详情

前端学习(3277):promise的使用

  查看详情

poj3277cityhorizon

CityHorizonTimeLimit: 2000MS MemoryLimit: 65536KTotalSubmissions: 18555 Accepted: 5114DescriptionFarmerJohnhastakenhiscowsonatriptothecity!Asthesunsets,thecowsgazeattheci 查看详情

灵动微m3内核32位单片机lqfp100封装mm32f3277g8p

灵动微MM32F3277G8P使用高性能的ARM®Cortex®M3为内核的32位单片机,ARM®的Cortex®M3微控制器是一个可配置的并具有多级流水线的32位精简指令集处理器,具有高性能和低功耗的特点。MM32F3277G8P包含多达3个12位的ADC、2个比较器、2个16位... 查看详情

bzoj3277串(代码片段)

https://www.lydsy.com/JudgeOnline/problem.php?id=3277把多个串插入广义后缀自动机中,建出parent树,在树上做set启发式合并,记录下每一个前缀在不同串出现的次数,再对每个串暴力匹配一遍,求出答案即可.复杂度O(nlogn)1#include<algorithm>2... 查看详情

如何解决 .net 核心构建错误 NETDSDK1061 和警告 MSB3277

】如何解决.net核心构建错误NETDSDK1061和警告MSB3277【英文标题】:Howtoresolve.netcorebuilderrorNETDSDK1061andwarningMSB3277【发布时间】:2019-03-0206:01:49【问题描述】:我遇到了问题,我的AspNetCore.App-metapackage引用的EntityFrameworkCore(2.1.2)版本低... 查看详情

bzoj3277串

TimeLimit: 10Sec  MemoryLimit: 128MBSubmit: 568  Solved: 233Description字符串是oi界常考的问题。现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包... 查看详情

[bzoj3277]串广义后缀自动机(代码片段)

3277:串TimeLimit: 10Sec  MemoryLimit: 128MBSubmit: 811  Solved: 329[Submit][Status][Discuss]Description字符串是oi界常考的问题。现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k... 查看详情

mm32f3277micropython实验板设计和软件测试(代码片段)

 §01设计要求在制作测试MM32F3277-MicroPython最小电路板测试了基于MM32F3277的MicroPython测试板。也可以看到它的时钟是不需要。下面设计一个适应于面包板进行测试实验的MicroPython测试板。一、资源设置1、MicroPython支持模块下面使用... 查看详情

设计带有sd卡的mm32f3277micropython实验板(代码片段)

简介:本文测试了基于MM32F3277下的MicroPython电路板设计。其中包含有SD卡接口,常用外设接口等。验证了现在的移植的MicroPython的对文件的基本操作功能。关键词:MM32F3277,MicroPython,SD卡 §01设计背景一、MM32F32... 查看详情

制作灵动单片机mm32f3277测试版(代码片段)

...了在Windows7下安装基于MM32-LINK开发软件。设计制作了MM32F3277的测试电路板,并对如何正确从MM32-LINK将调试电缆连接至MM32F3277开发板进行介绍。需要保证编程电流长度以及线序都满足要求,才能够正确完成程序高速下载。关... 查看详情

bzoj3277:串

Description字符串是oi界常考的问题。现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身)。Solution出现\(k\)次的问题比较好解决,我们构出\(parent\)树,然后在上... 查看详情

制作测试mm32f3277-micropython最小电路板(代码片段)

简介:设计制作了基于MM32F3277的MicroPython测试电路,下载了来自于SeekFree已知的MicroPython,证明它可以完成正常使用。关键词:MM32F3277,MicroPython,快速制版 §01参考设计一、设计背景  在前天已经通过以... 查看详情

bzoj3277串(代码片段)

题目描述题解:对于多串的子串,我们可以建出广义后缀自动机。由于本题询问的是(子串出现次数>=k)×len的总和,就将所有串扔到自动机中,爆跳pre并标记。每个点得到一个经过次数cnt。若cnt>=k,说明这个点压缩的所有... 查看详情

bzoj3277:串(代码片段)

以下全部是笔记,不要看了注意:要求的不是"有多少不同的子串是...",相同的要重复计算贡献。例如:32acaac答案是311第一个串中两个a都出现了两次,c出现了两次,所以第一个的答案是3广义后缀自动机模板。各个串连起来中间... 查看详情

并不对劲的bzoj3277

陈年老坑题意大概是有n个字符串,要求出每一个字符串的所有子串(不包括空串)在所有字符串(包括自身)中出现次数不少于k的有多少个。n,k,字符串总长<=100000。如果只有一个串的话,非常好办,直接把它建成后缀自动机... 查看详情

mm32f3277micropython移植过程中对应的接口文件(代码片段)

简介:给出了在MM32移植MicroPython过程中基础语法中Pin相关的内容。关键词:MM32F3277,machine,Pin §01MacinePin/*machine_pin.h*/#ifndef__MACHINE_PIN_H__#define__MACHINE_PIN_H__#include"py/runtime.h 查看详情

hdu1829(种类并查集)

ps:本来是想找个二分图判断的题来写,结果百度到这鬼题 ProblemDescriptionBackgroundProfessorHopperisresearchingthesexualbehaviorofararespeciesofbugs.Heassumesthattheyfeaturetwodifferentgendersandthattheyonlyinteractwithbug 查看详情