zoukankan      html  css  js  c++  java
  • UVA 12549 Sentry Robots (最小点覆盖)

    这道题挺像hdu 5093 Battle ships的,不过那道题是要求最多放置的点数,而这道题是要求最小点覆盖。

    顶点覆盖的定义是:在G中任意边至少有一个端点属于顶点集合S。

    一个重要的位置有(x,y)两个坐标,而要守住这个这个位置就是相当于连了一条边x到y的边。

    选了一个(x,y)就相当于选了所有相同的x的边或者所有相同的y的边。

    当所有的x或y被选完的时候就完成了看守。相当于是割断了x和y,所以就是最小割,对于容量为1的模型可以用匈牙利算法。

    有了障碍以后只要把障碍两边的分开考虑就行了,拆一下点。

    数组开大点不要RE啦

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 5002;
    const int maxn = 101;
    char g[maxn][maxn];
    int Yid[maxn][maxn],Y_cnt;
    int match[N];
    int dfsT[N],dfsTime;
    vector<int> G[N];
    #define PB push_back
    bool dfs(int u)
    {
        for(int i = 0; i < G[u].size(); i++){
            int v = G[u][i];
            if(dfsT[v] != dfsTime){
                dfsT[v] = dfsTime;
                if(!~match[v] || dfs(match[v])){
                    match[v] = u; return true;
                }
            }
        }
        return false;
    }
    
    int MaxMatch()
    {
        int ret = 0;
        memset(match,-1,sizeof(match));
        memset(dfsT,0,sizeof(dfsT));
        dfsTime = 0;
        for(int i = 0; i < Y_cnt; i++){
            dfsTime++;
            if(dfs(i)) ret++;
        }
        return ret;
    }
    
    int main()
    {
       // freopen("in.txt","r",stdin);
        int C; scanf("%d",&C);
        while(C--){
            int Y, X, P; scanf("%d%d%d",&Y,&X,&P);
            memset(g,0,sizeof(g));
    
            while(P--) {
                int r,c;scanf("%d%d",&r,&c);
                g[r][c] = '*';
            }
            scanf("%d",&P);
            while(P--){
                int r,c;scanf("%d%d",&r,&c);
                g[r][c] = '#';
            }
            Y_cnt = 0;
            for(int i = 1; i <= Y;i++){
                bool flag = false;
                for(int j = 1; j <= X; j++){
                    if(g[i][j] == '*') flag = true,Yid[i][j] = Y_cnt;
                    else if(g[i][j] == '#' && flag) Y_cnt++;
                }
                if(flag) Y_cnt++;
            }
            for(int i = 0; i < Y_cnt; i++) G[i].clear();
            int X_cnt = 0;
            for(int j = 1; j <= X; j++){
                bool flag = false;
                for(int i = 1; i <= Y; i++){
                    if(g[i][j] == '*') {
                        flag = true;
                        G[Yid[i][j]].PB(X_cnt);
                    }else if(g[i][j] == '#'&&flag){
                        X_cnt++;
                    }
                }
                if(flag) X_cnt++;
            }
            printf("%d
    ",MaxMatch());
        }
        return 0;
    }
  • 相关阅读:
    [转]Go语言中的make和new
    Python中的get和set方法
    协程是个啥玩意
    聊聊Python中的is和==
    聊聊Python中的闭包和装饰器
    聊聊Python中的生成器和迭代器
    聊聊动态语言那些事(Python)
    在mac上安装svn客户端
    关于mac mini组装普液晶显示器
    IOS 日志输出控制
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4770184.html
Copyright © 2011-2022 走看看