Magic Ball problems (network flow, bipartite graph)

Magic Ball problems (luogu)

Description

Title Description

"Problem Description:

Suppose there are n columns, the following rules are now Yaoan the n columns sequentially into numbered 1,2,3, ... ball.

(1) You can only put the ball at the top of a pillar.

(2) in a same column, any two adjacent balls is the sum of the number of perfect squares.

Try to design an algorithm to calculate the maximum number of balls can be put on the n columns. For example, in the four columns can hold up to 11 balls.

<< programming tasks:

For a given n, calculating the maximum number of balls can be put on the n columns.

Input Format

Line 1 has a positive integer n, the number of columns.

Output Format

When the run is finished, the n columns up to the number of balls put in place and the corresponding program output. The first line of the file is the number of balls.

The next n lines, each line are numbered balls on a pillar.

4<=n<=55

 

Solution

Constraints between "turn into numbered 1,2,3, ... the ball" and has placed on the same pillar of the ball reminds us that the minimum coverage about the waypoint.

I numbered from the ball to the ball can be placed behind it even a directed edge,

Since each ball should be placed, this question becomes the minimum number of points required to cover the waypoints up to the point n of FIG.

A bipartite graph can be done (and faster than network flow qwq)

 

Code

 

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
const int N=6010,M=5000001;
int head[N],ver[M],nxt[M],tot;
int n,ans=1,match[N],vis[N],cnt,pp,pre[N];
bool flag[N];
vector <int> an;
bool is(int x)
{
    int y=sqrt(x);
    return y*y==x;
}
bool dfs(int x)
{
    for(int i=head[x],y;i;i=nxt[i])
        if(vis[y=ver[i]]!=cnt)
        {
            vis[y]=cnt;
            if(!match[y] || dfs(match[y]))
            {
                match[y]=x,match[x]=y;
                return 1;
            }
        }
    return 0;
}
void add(int x,int y)
{
    ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;
}
int main()
{
    scanf("%d",&n);
    for(;;ans++)
    {
        cnt++;
        for(int i=ans+1;i<ans*2;i++)
            if(is(i)) add(ans,i-ans+3000);
        memcpy(pre,match,sizeof(pre));
        if(dfs(ans)) pp++;
        if(ans-pp>n) break;
    }
    printf("%d\n",ans-1);
    for(int i=ans-1;i>=1;i--)
        if(!flag[i])
        {
            int x=i;
            an.clear();
            while(x>0) an.push_back(x),flag[x]=true,x=pre[x]-3000;
            int size=an.size();
            for(int j=size-1;j>=0;j--)
                printf("%d ",an[j]);
            puts("");
        }
    return 0;
}

 

 

 

 

Guess you like

Origin www.cnblogs.com/hsez-cyx/p/12350724.html