• 「网络流 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
  • 相关阅读:
    nyoj 311 完全背包
    HDU 1864 最大报销额
    HDU 1087 Super Jumping! Jumping! Jumping! 最长递增子序列(求可能的递增序列的和的最大值) *
    HDU 2602 Bone Collector
    1014 装箱问题 CODE[VS]
    JOBDU 1140 八皇后
    POJ 1979 Red and Black
    POJ 1129 Channel Allocation
    HDU 1863 畅通工程
    第二百四十七天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/shatianming/p/12227609.html
Copyright © 2020-2023  润新知