「网络流 24 题」魔术球

比较有意思的题

题意:给你n个柱子,问你可以在上面放多少个编号连续且每根柱子上相邻的编号为平方数的球
洗澡时候想的,根据平方数这个关系建边,然后枚举多少个柱子,然后再在图上跑最小路径覆盖,若路径条数大于柱子数,那么珠子数-1就是答案

我写的有点....t了,但不想改

#include<bits/stdc++.h>
using namespace std;

int n,tot=-1,h[3005],ans=0,hou[3005];
struct node{
    int from,next,to,rest,full;
    int last;
}e[1000005];
bool judge[60005];
void add(int x,int y,int z){
    tot++;
    e[tot].next=h[x];
    h[x]=tot;
    e[tot].from=x;
    e[tot].to=y;
    e[tot].rest=z;
    e[tot].full=z;
}

int dis[3005],g[3005],flow[3005];
bool vis[3005];

int bfs(int s,int t){
    queue<int>q;
    dis[s]=0;
    q.push(s);vis[s]=true;
    while(!q.empty()){
        int u=q.front();vis[u]=false;q.pop();
        for(int i=h[u];i!=(-1);i=e[i].next){
            if(dis[e[i].to]>dis[u]+1&&g[e[i].to]==(-1)&&e[i].rest>0){
                g[e[i].to]=i;
                flow[e[i].to]=min(flow[u],e[i].rest);
                dis[e[i].to]=dis[u]+1;
                if(vis[e[i].to]==false){
                    vis[e[i].to]=true;
                    q.push(e[i].to);
                }
            }
        }
    }
}

int EK(int s,int t){
    while(1){
        memset(dis,0x7f,sizeof(dis));
        memset(flow,0x7f,sizeof(flow));
        memset(g,-1,sizeof(g));
        bfs(s,t);
        if(g[t]==(-1))return 0;
        ans+=flow[t];
        for(int p=t;p!=(s);p=e[g[p]].from){
            e[g[p]].rest-=flow[t];
            e[g[p]^1].rest+=flow[t];
        }    
        
    }
}

int main(){
    memset(vis,false,sizeof(vis));
    memset(h,-1,sizeof(h));
    memset(hou,-1,sizeof(hou));
    cin>>n;
    int jy;
    for(int i=1;;i++){
        //cout<<i<<endl;
        int hj=4;
        for(int j=0;j<=tot;j++)e[j].rest=e[j].full;
        for(int j=1;j<i;j++){
            if(int(sqrt(j+i))*int(sqrt(j+i))==j+i){
                hj+=2;
                add(j,i+1500,1);
                add(i+1500,j,0);
            }
        }
        add(0,i,1);
        add(i,0,0);
        add(i+1500,3000,1);
        add(3000,i+1500,0);
        ans=0;
        EK(0,3000);
        if(i-ans>n){
            /*for(int j=0;j<=tot;j++){
            if(e[j].from==i||e[j].to==i||e[j].to==i+1234||e[j].from==i+1234){
                e[j].rest=0;
                e[j].full=0;        
                }
            }*/
            for(int j=0;j<hj;j++){
                h[e[tot-j].from]=e[tot-j].next;
            }
            jy=i-1;
            cout<<i-1<<endl;;
            break;
        }
        
    }
    
        for(int j=0;j<=tot;j++)e[j].rest=e[j].full;
        ans=0;
        EK(0,3000);
            for(int j=1;j<=jy;j++){
                for(int k=h[j];k!=(-1);k=e[k].next){
                    if(e[k].to!=0&&e[k].rest==0){
                        hou[j]=e[k].to-1500;
                        break;
                    }
                }
            }
            for(int j=1;j<=jy;j++){
                if(judge[j]==false){
                    cout<<j;judge[j]=true;
                    for(int now=hou[j];now!=(-1);now=hou[now]){
                        cout<<" "<<now;
                        judge[now]=true;
                    }
                    cout<<endl;
                }
            }
}
View Code
原文地址:https://www.cnblogs.com/shatianming/p/12227609.html