• BZOJ 1741: [Usaco2005 nov]Asteroids 穿越小行星群


    Description

    贝茜想驾驶她的飞船穿过危险的小行星群.小行星群是一个NxN的网格(1≤N≤500),在网格内有K个小行星(1≤K≤10000). 幸运地是贝茜有一个很强大的武器,一次可以消除所有在一行或一列中的小行星,这种武器很贵,所以她希望尽量地少用.给出所有的小行星的位置,算出贝茜最少需要多少次射击就能消除所有的小行星.

    Input

        第1行:两个整数N和K,用一个空格隔开.

        第2行至K+1行:每一行有两个空格隔开的整数R,C(1≤R,C≤N),分别表示小行星所在的行和列.

    Output

        一个整数表示贝茜需要的最少射击次数,可以消除所有的小行星

    题解:

    二分图,两列点分别表示行、列。

    对于一个点(x,y) 由 x向y连边。

    最小覆盖即是答案。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    //by zrt
    //problem:
    using namespace std;
    typedef long long ll;
    const double eps=1e-9;
    int H[505],P[10005],X[10005],tot;
    int n,k;
    inline void add(int x,int y){
        P[++tot]=y;X[tot]=H[x];H[x]=tot;
    }
    bool cover[505];
    int link[505];
    int ans;
    bool find(int k){
        for(int i=H[k];i;i=X[i]){
            if(!cover[P[i]]){
                int q=link[P[i]];
                link[P[i]]=k;
                cover[P[i]]=1;
                if(q==-1){
                    ans++;return true;
                }
                if(find(q)) return true;
                link[P[i]]=q;
            }
        }
        return false;
    }
    int main(){
        #ifdef LOCAL
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        scanf("%d%d",&n,&k);
        for(int i=0,x,y;i<k;i++){
            scanf("%d%d",&x,&y);
            add(x,y);
        }
        memset(link,-1,sizeof link);
        for(int i=1;i<=n;i++){
            memset(cover,0,sizeof cover);
            find(i);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    可持久化线段树学习笔记
    GDI+学习之路
    tcpdump——分析tcp关闭4次过程
    nasm过程调用
    ios学习:NSURLConnection 和 Json数据解析
    ios学习:文件简单读写
    JSONP原理及其简单封装
    JSP使用JSTL
    JDBC
    Apache无法正常启动的原因
  • 原文地址:https://www.cnblogs.com/zrts/p/bzoj1741.html
Copyright © 2020-2023  润新知