Explanation:

First of all, all the balls have to be put into the barrel, so each ball is connected to the feasible barrel

A bucket can hold up to three balls. Consider splitting a bucket into three points

Now the maximum number of half empty barrels is required. If only one point of a barrel matches, then cnt++

But it's possible that there are two points that could be split open and matched to the same bucket, resulting in a smaller answer

There is an ingenious method of drawing, which can separate the open points as much as possible

Three points and two sides of a bucket

In this way, in the case of finding the maximum match, the maximum number of matches placed together is 3, while the maximum number of matches separated is 4

It can solve the problem of maximizing the number of half empty barrels

As shown in the figure: (red is the matching edge)

However, the graph built in this way is not a bipartite graph, but a general graph

So we need to solve the maximum matching problem of general graphs

Tree with flowers

If a general graph has odd rings, it must not be a bipartite graph

If there is such a odd ring in a graph, it may contribute five matching edges

But its interior will only contribute 2 matching edges at most

At most, only one outer point can match the points in the odd ring

So we can consider reducing the odd ring to a point to find the path of augmentation

But after shrinking the points, there are only 1 + 2 matches in the graph that can match 5 edges

All of us can't shrink directly. When dfs reaches this point, we need to expand the shrinking point (flowering)

In this way, we can find the way to increase

The following paragraph is quoted from: https://www.cnblogs.com/owenyu/p/6858508.html

Paste template:

```#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 305
#define M 500005
int fir[N],to[M],nxt[M],cnt;
{
to[++cnt]=b;nxt[cnt]=fir[a];fir[a]=cnt;
to[++cnt]=a;nxt[cnt]=fir[b];fir[b]=cnt;
}
namespace FT{
int sz;
int fa[N],pre[N],mat[N],vis[N];
int q[N],he,ta;
int tim[N],tm;
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int lca(int x,int y){
for(tm++;;swap(x,y))if(x){
x=find(x);
if(tim[x]==tm)return x;
tim[x]=tm;x=pre[mat[x]];
}
}
void bls(int x,int y,int p){
while(find(x)!=p){
pre[x]=y;y=mat[x];
if(vis[y]==2)vis[y]=1,q[++ta]=y;
if(find(x)==x)fa[x]=p;
if(find(y)==y)fa[y]=p;
x=pre[y];
}
}
bool bfs(int s){
for(int i=1;i<=sz;i++)fa[i]=i;
memset(vis,0,sizeof(vis));memset(pre,0,sizeof(pre));
he=1;ta=0;q[++ta]=s;vis[s]=1;
while(he<=ta){
int u=q[he++];
for(int v,p=fir[u];p;p=nxt[p]){
if(vis[v=to[p]]==2||find(u)==find(v))continue;
if(!vis[v]){
vis[v]=2;pre[v]=u;
if(!mat[v]){
for(int tmp;v;v=tmp){
tmp=mat[u=pre[v]];
mat[v]=u;mat[u]=v;
}
return 1;
}
vis[mat[v]]=1;q[++ta]=mat[v];
}
else{
int x=lca(u,v);
bls(u,v,x);bls(v,u,x);
}
}
}
return 0;
}
}//----FT----```

Code:

```#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 605
#define M 500005
int fir[N],to[M],nxt[M],cnt;
{
to[++cnt]=b;nxt[cnt]=fir[a];fir[a]=cnt;
to[++cnt]=a;nxt[cnt]=fir[b];fir[b]=cnt;
}
int fa[N],pre[N],match[N],vis[N],q[N],he,ta;
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int sz,tim[N],tm;
int lca(int x,int y)
{
for(tm++;;swap(x,y))if(x){
x=find(x);
if(tim[x]==tm)return x;
else tim[x]=tm,x=pre[match[x]];
}
}
void bls(int x,int y,int p)
{
while(find(x)!=p){
pre[x]=y;y=match[x];
if(vis[y]==2)vis[y]=1,q[++ta]=y;
if(find(x)==x)fa[x]=p;
if(find(y)==y)fa[y]=p;
x=pre[y];
}
}
bool bfs(int s)
{
for(int i=1;i<=sz;i++)fa[i]=i;
memset(vis,0,sizeof(vis));memset(pre,0,sizeof(pre));
he=1;ta=0;q[++ta]=s;vis[s]=1;
while(he<=ta){
int u=q[he];he++;
for(int v,p=fir[u];p;p=nxt[p]){
if(vis[v=to[p]]==2||find(v)==find(u))continue;
if(!vis[v]){
vis[v]=2;pre[v]=u;
if(!match[v]){
for(int tmp;v;v=tmp){
tmp=match[u=pre[v]];
match[v]=u,match[u]=v;
}
return 1;
}
vis[match[v]]=1;q[++ta]=match[v];
}
else{
int x=lca(u,v);
bls(u,v,x);
bls(v,u,x);
}
}
}
return 0;
}
int main()
{
int T,n,m,E,i,u,v;
scanf("%d",&T);
while(T--){
memset(fir,0,sizeof(fir));cnt=0;
memset(match,0,sizeof(match));
scanf("%d%d%d",&n,&m,&E);
sz=n+3*m;
for(i=1;i<=E;i++){
scanf("%d%d",&u,&v);
}
for(i=1;i<=m;i++){
}
int ans=0;
for(i=1;i<=sz;i++)
if(!match[i])ans+=bfs(i);
printf("%d\n",ans-n);
printf("%d",(match[1]-n-1)%m+1);
for(i=2;i<=n;i++)
printf(" %d",(match[i]-n-1)%m+1);
printf("\n");
}
}```

Posted on Wed, 10 Jun 2020 02:31:27 -0400 by phpnewbie8