• UVA 12125 March of the Penguins


    题意:

      给定一些冰块,每个冰块上有一些企鹅,每个冰块有一个可以跳出的次数限制,每个冰块位于一个坐标,现在每个企鹅跳跃力为d,问所有企鹅能否跳到一点上,如果可以输出所有落脚冰块,如果没有方案就打印-1

    分析:

      很显然的最大流问题。把每个冰块x拆成x和x',连x->x'流量为跳出的次数限制。枚举落脚冰块建图跑最大流即可

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <queue>
    using namespace std;
    const int maxn = 202 + 10;
    const int INF = 1000000000;
    struct Edge
    {
        int from,to,cap,flow;
    };
    struct Dinic
    {
        int n,m,s,t;
        vector<Edge>edges;
        vector<int>G[maxn];
        bool vis[maxn];
        int d[maxn];
        int cur[maxn];
        void clearall(int n)
        {
            for(int i=0;i<n;i++)
                G[i].clear();
            edges.clear();
        }
        void clearflow()
        {
            for(int i=0;i<edges.size();i++)
                edges[i].flow=0;
        }
        void addedge(int from,int to,int cap)
        {
            edges.push_back((Edge){from,to,cap,0});
            edges.push_back((Edge){to,from,0,0});
            m=edges.size();
            G[from].push_back(m-2);
            G[to].push_back(m-1);
        }
        bool bfs()
        {
            memset(vis,0,sizeof(vis));
            queue<int>Q;
            Q.push(s);
            vis[s]=1;
            d[s]=0;
            while(!Q.empty())
            {
                int x=Q.front();
                Q.pop();
                for(int i=0;i<G[x].size();i++)
                {
                    Edge& e=edges[G[x][i]];
                    if(!vis[e.to]&&e.cap>e.flow)
                    {
                        vis[e.to]=1;
                        d[e.to]=d[x]+1;
                        Q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
        int dfs(int x,int a)
        {
            if(x==t||a==0)
            {
                return a;
            }
            int flow=0,f;
            for(int& i=cur[x];i<G[x].size();i++)
            {
                Edge& e=edges[G[x][i]];
                if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
                {
                    e.flow+=f;
                    edges[G[x][i]^1].flow -= f;
                    flow+=f;
                    a-=f;
                    if(a==0)
                        break;
                }
            }
            return flow;
        }
        int maxflow(int s,int t)
        {
            this->s=s;
            this->t=t;
            int flow=0;
            //cout<<2<<endl;
            while(bfs())
            {
                memset(cur,0,sizeof(cur));
                flow+=dfs(s,INF);
            }
            //cout<<3<<endl;
            return flow;
        }
    };
    struct Node
    {
        int x,y,num;
    }p[maxn];
    Dinic solver;
    double dis(Node a,Node b)
    {
        return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    }
    vector<int>ans;
    int main()
    {
        int t,n,total;
        double D;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%lf",&n,&D);
            solver.clearall(2*n+1);
            int s1=0;
            total=0;
            D=D*D;
            for(int i=1;i<=n;i++)
            {
                int x,y,ni,cap;
                scanf("%d%d%d%d",&x,&y,&ni,&cap);
                p[i].x=x;p[i].y=y;p[i].num=ni;
                total+=ni;
                solver.addedge(s1,i,ni);
                solver.addedge(i,i+n,cap);
            }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                     if(i != j && D-dis(p[i],p[j])> 1e-6)
                     {
                        solver.addedge(i+n,j,INF);
                     }
            int sum=0;
            ans.clear();
            //cout<<1<<endl;
            for(int i=1;i<=n;i++)
            {
                solver.clearflow();
                if(solver.maxflow(s1,i)==total)
                {
                    ans.push_back(i);
                    sum++;
                }
            }
            //cout<<sum<<endl;
            if(sum==0)
                printf("-1
    ");
            else
            {
                for(int i=0;i<ans.size()-1;i++)
                    printf("%d ",ans[i]-1);
                printf("%d
    ",ans[ans.size()-1]-1);
            }
        }
    }

    输入:

    2

    5 3.5

    1 1 1 1

    2 3 0 1

    3 5 1 1

    5 1 1 1

    5 4 0 1

    3 1.1

    -1 0 5 10

    0 0 3 9

    2 0 1 1

  • 相关阅读:
    通讯技术
    (1)sqlserver2017安装
    c# api身份验证和授权
    ()centos7 安装python36
    python 包管理
    ()centos7 安装mysql8.0
    [bzoj1095][ZJOI2007]Hide 捉迷藏 点分树,动态点分治
    bzoj 3544 [ONTAK2010]Creative Accounting 贪心
    BZOJ4300 绝世好题 dp
    bzoj 4295 [PA2015]Hazard 贪心,暴力
  • 原文地址:https://www.cnblogs.com/137033036-wjl/p/5763701.html
Copyright © 2020-2023  润新知