• 「网络流 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
  • 相关阅读:
    asp.net中获取网站根目录和物理路径的方法
    解决Windows 程序界面闪烁问题的一些经验
    winform中怎样使DataGridView的某一列可以添加两个Button控件
    Asp.net中实现多语言的Page的扩展的基类
    c#自杀程序的关键方法
    30岁前成功的12条黄金法则
    分享一个收集到的文件和目录操作类FileSystemObject
    有时候我们需要搜索指定栏目下的文章,如何实现呢?
    安静删除服务器超级多的文件,有的文件夹文件过多而不方便删除
    SQLServer2005数据库备份与还原
  • 原文地址:https://www.cnblogs.com/shatianming/p/12227609.html
Copyright © 2020-2023  润新知