• LibreOJ 6003 魔术球 (最大流)


    题解:每次加入两个点,对于和为平方数的两个值所对应的点建边,反正网络流可以跑残量网络,所以就没有什么关系了……

    代码如下:

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int head[100010],next[100010],w[100010],v[100010],deep[100010];
    int s,t,cnt;
    
    
    void init()
    {
        cnt=-1;
        memset(head,-1,sizeof(head));
        memset(next,-1,sizeof(next));
    }
    
    void add(int from,int to,int cost)
    {
        cnt++;
        next[cnt]=head[from];
        w[cnt]=cost;
        v[cnt]=to;
        head[from]=cnt;
    }
    
    void add_edge(int from,int to,int cost)
    {
        add(from,to,cost);
        add(to,from,0);
    }
    
    int bfs(int s,int t)
    {
        queue<int> q;
        memset(deep,0,sizeof(deep));
        deep[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u]; i!=-1; i=next[i])
            {
                if(!deep[v[i]]&&w[i]>0)
                {
                    deep[v[i]]=deep[u]+1;
                    q.push(v[i]);
                }
            }
        }
        if(!deep[t])
        {
            return 0;
        }
        return 1;
    }
    
    int dfs(int u,int t,int dist)
    {
        if(u==t)
        {
            return dist;
        }
        for(int i=head[u]; i!=-1; i=next[i])
        {
            if(w[i]&&(deep[u]+1==deep[v[i]]))
            {
                int di=dfs(v[i],t,min(w[i],dist));
                if(di>0)
                {
                    w[i]-=di;
                    w[i^1]=di;
                    return di;
                }
            }
        }
        return 0;
    }
    
    int dinic(int s,int t)
    {
        int ans=0;
        while(bfs(s,t))
        {
            while(int d=dfs(s,t,inf))
            {
                ans+=d;
            }
        }
        return ans;                //
    }
    
    int id[11110],wid[11110],vis[11110];
    void solve(int x,int &f)
    {
        int loc=wid[x];
        vis[x]=1;
        for(int i=head[loc]; i!=-1; i=next[i])
        {
            if(w[i]==1&&v[i]!=t)
            {
                solve(v[i]/2,f);
            }
        }
        if(f==1)
        {
            f=0;
        }
        else
        {
            putchar(' ');
        }
        printf("%d",x);
    }
    
    int main()
    {
        init();
        int n;
        scanf("%d",&n);
        s=0;
        t=11110;
        int i,tmp=2,ans=0,tmp2=0;
    
        for(i=1; i-ans<=n+1; i++)
        {
            id[i]=tmp++;
            wid[i]=tmp++;
            add_edge(s,id[i],1);
            add_edge(wid[i],t,1);
            for(int j=1; j<i; j++)
            {
                int tmp1=sqrt(i+j);
                if(tmp1*tmp1==i+j)
                {
                    add_edge(id[j],wid[i],1);
                }
            }
            ans+=dinic(s,t);
        }
        tmp2=i-2;
        printf("%d
    ",tmp2);
        for(int i=head[t]; i!=-1; i=next[i])
        {
            if(w[i]==1&&!vis[v[i]/2])
            {
                int f=1;
                solve(v[i]/2,f);
                puts("");
            }
        }
        for(int i=1; i<=tmp2; i++)
        {
            if(!vis[i])
            {
                printf("%d
    ",i);
            }
        }
    }
  • 相关阅读:
    hadoop安全模式
    建造者模式:设计角度重温游戏中的角色
    工厂模式:工厂方法与抽象工厂的战争
    原型模式(克隆模式):浅谈浅克隆与深克隆
    单例模式:层层剖析寻找最高效安全的单例
    24种设计模式和7大设计原则
    浅谈图的存储结构与遍历
    彻底理清二叉排序树的插入、查找、删除
    浅谈顺序、折半查找
    Android定位(是否使用GPS进行定位)
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/8584391.html
Copyright © 2020-2023  润新知