zoukankan      html  css  js  c++  java
  • 【codevs1922】骑士共存问题——网络流

    给棋盘黑白染色,源点向不为障碍的奇点连一条权值为1的边,向可以攻击到的偶点连一条边,权值为inf;偶点向汇点(t=n*n+1)连一条权值为1的边。

    跑最小割,最小割的意义就是看至少要放弃几个点(即这里不放骑士)才能使他们不会互相攻击,最后用总格数减去最小割时记得也要减去障碍数,即n*n-ans-m.

    具体细节看代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    const int inf=0x3f3f3f3f;
    using namespace std;
    int n,m,s,t;
    struct point
    {
        int flow,to,next;
    }e[500500];
    int q[40050],d[40050],tot=1,first[40010],cur[40010];
    bool mapp[204][204];
    int cc[10][2]={{1,2},{2,1},{-1,2},{-1,-2},{1,-2},{2,-1},{-2,1},{-2,-1}};
    void insert(int u,int v,int w)
    {
        tot++;e[tot].to=v;e[tot].flow=w;e[tot].next=first[u];first[u]=tot;
        tot++;e[tot].to=u;e[tot].flow=0;e[tot].next=first[v];first[v]=tot;
    }
    bool bfs()
    {
        memset(d,-1,sizeof(d));
        d[0]=0;q[0]=0;
        int head=0,tail=1;
        while(head!=tail)
        {
            int x=q[head++];if(head>=40000)head=0;
            for(int i=first[x];i;i=e[i].next)
            {
                if(d[e[i].to]==-1&&e[i].flow>0)
                {
                    d[e[i].to]=d[x]+1;
                    q[tail++]=e[i].to;
                    if(tail>=40000)tail=0;
                }
            }
        }
        if(d[t]==-1)return false;
        return true;
    }
    int dfs(int x,int a)
    {
        if(x==t||a==0)return a;
        int flow=0,f;
        for(int& i=cur[x];i;i=e[i].next)
        {
            if(d[e[i].to]==d[x]+1&&(f=dfs(e[i].to,min(a,e[i].flow)))>0)
            {
                e[i].flow-=f;
                e[i^1].flow+=f;
                a-=f;
                flow+=f;
                if(!a)break;
            }
        }
        return flow;
    }
    int sum(int x,int y)
    {
        return (x-1)*n+y;
    }
    int main()
    {
        int x,y,ans=0;
        scanf("%d %d",&n,&m);
        s=0;t=n*n+1;
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d",&x,&y);
            mapp[x][y]=1;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(!mapp[i][j]&&!((i+j)%2))
                {
                    insert(s,sum(i,j),1);
                    for(int k=0;k<8;k++)
                    {
                        int xx=cc[k][0],yy=cc[k][1];
                        if(i+xx>0&&i+xx<=n&&j+yy>0&&j+yy<=n&&!mapp[i+xx][j+yy])insert(sum(i,j),sum(i+xx,j+yy),inf);
                    }
                }
                else if(!mapp[i][j])insert(sum(i,j),t,1);
            }
        }
        while(bfs())
        {
            for(int i=0;i<=t;i++)cur[i]=first[i];
            ans+=dfs(0,inf);
        }
        printf("%d
    ",n*n-ans-m);
        return 0;
    }
    View Code
  • 相关阅读:
    HDU 1874 畅通工程续(dijkstra)
    HDU 2112 HDU Today (map函数,dijkstra最短路径)
    HDU 2680 Choose the best route(dijkstra)
    HDU 2066 一个人的旅行(最短路径,dijkstra)
    关于测评机,编译器,我有些话想说
    测评机的优化问题 时间控制
    CF Round410 D. Mike and distribution
    数字三角形2 (取模)
    CF Round410 C. Mike and gcd problem
    CF Round 423 D. High Load 星图(最优最简构建)
  • 原文地址:https://www.cnblogs.com/JKAI/p/7003034.html
Copyright © 2011-2022 走看看