sgu 242 Student's Morning--最大流 或 多重匹配

/*
n同学分别来自不同的学校,他们想去学校玩,但是不像一个人去,所以去某个学校的人数应>=2
问是否有k个学校满足要求

建边:
[s,学校] 权为2
[学校,同学] 权为1
[同学,t] 权为1


据说这题可以用匹配做,以后看看
*/
#include
#include
#define inf 0x7ffffff
struct edge
{
	int u,v,f,next;
}e[100010];
int head[410],yong;
int n,k,s,t;
void ini()
{
	memset(head,-1,sizeof(head));
	yong=0;
	s=0,t=2*n+1;
}
void adde(int from,int to,int flow)
{
	e[yong].u=from,e[yong].v=to,e[yong].f=flow;
	e[yong].next=head[from],head[from]=yong++;

	e[yong].u=to,e[yong].v=from,e[yong].f=0;
	e[yong].next=head[to],head[to]=yong++;
}
int d[410],num[410];  
int min(int a,int b){return a0)
        {      
            if(d[u]==d[v]+1)      
            {      
                cost=sap_gap(v,min(last,flow),s,t);      
                e[i].f-=cost;      
                e[i^1].f+=cost;      
                last-=cost;      
      
                if(d[s]>=t+1)      
                    return f-last;      
      
                if(last==0)      
                    break;      
            }      
            if(d[v]


写了两种多重匹配:1.拆点2.用结构体表示多重匹配点

前者适用于所有点的多重匹配数量相同

后者没什么限制

/*
用多重匹配写的

把每个学校拆成两个点 然后匹配
*/
#include
using namespace std;
int n,k;
int map[210][410];
int match[410],vis[410];
int dfs(int i)
{
	int j;
	for(j=0;j>n>>k)
	{
		memset(map,0,sizeof(map));
		for(i=0;i>nn;
			while(nn--)
			{
				cin>>a;
				map[i][(a-1)*2]=1;
				map[i][(a-1)*2+1]=1;
			}
		}
		a=0;
		memset(match,-1,sizeof(match));
		for(i=0;i



/*
用多重匹配写的

每个学校是一个结构体,里边保存匹配信息

对应普通匹配的  if(match[j]==-1||dfs(match[j]))
多重匹配则是    if(匹配还未用完) 匹配成功     相当于match[j]==-1
				else 尝试替换某个匹配         相当于dfs(match[j])
*/
#include
#include
using namespace std;
int n,k;
int map[210][210],vis[210];
struct node
{
	int n;
	vectormatch;
}school[210];
int dfs(int i)
{
	int j,k;
	for(j=0;j0)
			{
				--school[j].n;
				school[j].match.push_back(i);
				return 1;
			}
			for(k=0;k>n>>k)
	{
		for(i=0;i>nn;
			while(nn--)
			{
				cin>>a;
				map[i][a-1]=1;
			}
		}

		a=0;
		for(i=0;i



你可能感兴趣的:(最大流,二分图匹配,模版)