zoukankan      html  css  js  c++  java
  • 小行星群 网络流 二分图

    小行星群

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    贝西驾驶着宇宙飞船,准备穿过危险的小行星群。它所在的星域可以分为 N × N 个网格,小行
    星存在于其中的 M 个网格。贝西要安全通过这片星域,必须消灭所有的小行星。好在她有一件终极
    兵器——地图炮。只要一发炮弹就可以清除同一行或同一列网格里的所有小行星。这种弹药很贵,所
    以贝西希望尽量少来几发。给出所有的小行星的位置,请算出最少需要几发炮弹才能消灭它们。

    输入

    • 第一行:两个整数 N 和 M,1 ≤ N ≤ 500, 1 ≤ M ≤ 10 4
    • 第二行到第 M + 1 行:第 i + 1 行有两个整数 R i 和 C i ,1 ≤ R i ,C i ≤ N

    输出

    • 单个整数:表示最少需要发射的多少炮弹

    样例输入

    3 4 1 1 1 3 2 2 3 2

    样例输出

    2

    提示

    向第一行开炮,消灭 (1,1) 和 (1,3),再向第

    二列开炮,消灭 (2,2) 和 (3,2)
    题解:
    此题可以用网络流最大流解决,
    1.源点和每一行连接,汇点和每一列连接,残量为1。
    2.根据输入的情况将行和列连一条残量为1的边。
    3.然后就是最大流了。
    当然二分图对于这道题来说效率更高,这里只提供最大流代码。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    using namespace std;
    int n,m;
    struct node
    {
        int next,to,cap;
    }edge[600001];
    int head[2001],size=1;
    void putin(int from,int to,int cap)
    {
        size++;
        edge[size].to=to;
        edge[size].cap=cap;
        edge[size].next=head[from];
        head[from]=size;
    }
    void in(int from,int to,int cap)
    {
        putin(from,to,cap);
        putin(to,from,0);
    }
    int dist[2001],numbs[2001];
    void bfs(int src,int des)
    {
        int i,j;
        queue<int>mem;
        for(i=0;i<=n*2+1;i++){dist[i]=n*2+2;numbs[i]=0;}
        mem.push(des);
        dist[des]=0;numbs[0]=1;
        while(!mem.empty())
        {
            int x=mem.front();mem.pop();
            for(i=head[x];i!=-1;i=edge[i].next)
            {
                int y=edge[i].to;
                if(dist[y]==n*2+2&&edge[i].cap==0)
                {
                    dist[y]=dist[x]+1;
                    numbs[dist[y]]++;
                    mem.push(y);
                }
            }
        }
        return;
    }
    int dfs(int src,int flow,int des)
    {
        if(src==des)return flow;
        int low=0,i,mindist=n*2+2;
        for(i=head[src];i!=-1;i=edge[i].next)
        {
            int y=edge[i].to;
            if(edge[i].cap)
            {
                if(dist[y]==dist[src]-1)
                {
                    int t=dfs(y,min(flow-low,edge[i].cap),des);
                    edge[i].cap-=t;
                    edge[i^1].cap+=t;
                    low+=t;
                    if(dist[0]==n*2+2)return low;
                    if(flow==low)break;
                }
                mindist=min(mindist,dist[y]+1);
            }
        }
        if(!low)
        {
            if(!(--numbs[dist[src]]))dist[0]=n*2+2;
            ++numbs[dist[src]=mindist];
        }
        return low;
    }
    int ISAP(int src,int des)
    {
        int ans=0;
        bfs(src,des);
        while(dist[src]<n*2+2)ans+=dfs(src,2e8,des);
        return ans;
    }
    int main()
    {
        int i,j;
        scanf("%d%d",&n,&m);
        memset(head,-1,sizeof(head));
        for(i=1;i<=n;i++)in(0,i,1);
        for(i=n+1;i<=n*2;i++)in(i,n*2+1,1);
        for(i=1;i<=m;i++)
        {
            int from,to;
            scanf("%d%d",&from,&to);
            in(from,to+n,1);
        }
        int maxflow=ISAP(0,2*n+1);
        cout<<maxflow;
        return 0;
    }
  • 相关阅读:
    POJ 1251 Jungle Roads 最小生成树
    HDU 1879 继续畅通工程 最小生成树
    HDU 1875 畅通工程再续 最小生成树
    HDU 1863 畅通工程 最小生成树
    CodeForces 445B DZY Loves Chemistry (并查集)
    UVA 11987 Almost Union-Find (并查集)
    UVALive(LA) 4487 Exclusive-OR(带权并查集)
    UVALive 3027 Corporative Network (带权并查集)
    UVALive(LA) 3644 X-Plosives (并查集)
    POJ 2524 Ubiquitous Religions (并查集)
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/6905091.html
Copyright © 2011-2022 走看看