• hdu1507--二分图最大匹配


    题意:你大爷。哦不!

    你大叔继承了一块地什么的都是废话。。安静,这里说说题意,和怎么建图。

    题意:这里有一块N*M的地,可是有 K 个地方。是池塘,然后输入K行(x,y),OK,如今能够出售的地必须是 1*2 大小的矩形,而且不能是池塘。。。

    问。在N*M的这块地上。能有多少块地能够出售,而且。要输出这些能够出售的地的坐标。

    建图:那么这里事实上和我之前做过的hdu4185 差点儿相同1A。

    http://blog.csdn.net/zyy173533832/article/details/12654539

    那么能够预先处理一下,把N*M的地图中,是土地的按 1,2,3....编号。在这里我们须要对于每一个编号。记录这个编号的土地的坐标。那么这里他说了N*M-K <= 50。那么我们接着对于每一个土地,遍历四个方向,看看有木有能够组在一起变成能卖的地。然后。。。然后图就建好啦。

    那么在二分匹配的过程中也要注意的是:匹配好的数量须要÷2,输出的时候也有点须要注意的,直接看代码中的解释:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    
    #define MAX 105
    
    int N,M,K;
    int map[MAX][MAX];
    int loc[MAX/2][2];//这里是依据编号记录坐标   如第2个地的坐标 (loc[2][0] , loc[2][1]) 
    int node_num; //点数,也就是土地的数量。编号的那个
    
    struct Edge{//邻接表
        int to,next;
    }edge[MAX*4];
    int head[MAX/2],edge_num;
    
    void add(int u,int v){
        edge[edge_num].to = v;
        edge[edge_num].next = head[u];
        head[u] = edge_num++;
    }
    
    int vis[4][2]={0,1,0,-1,1,0,-1,0};
    
    void initMap(){
        node_num = 1;
        memset(map,0,sizeof(map));
    
        int x,y;
        while(K --){
            cin >> x >> y;
            map[x][y] = -1;//表示此地不可用。是池塘
        }
    
        for(int i = 1; i <= N; i ++){
            for(int j = 1; j <= M; j ++){
                if(!map[i][j]) {
                     map[i][j] = node_num++;
                     loc[node_num-1][0] = i; loc[node_num-1][1] = j;//记录坐标
                }
            }
        }
    
        edge_num = 0;
        memset(head,-1,sizeof(head));
        for(int i = 1; i <= N; i ++){
            for(int j = 1; j <= M; j ++){
                if(map[i][j] != -1){
                    for(int k = 0; k < 4; k ++)
                    {
                        int x = i+vis[k][0],y = j+vis[k][1];
                        if(map[x][y] != -1 && x >=1 && y >= 1 && x <= N && y <= M)
                        {
                            add(map[i][j],map[x][y]); add(map[x][y],map[i][j]);
                        }
                    }
                }
            }
        }
    }
    //------------------------
    bool useif[MAX/2];
    int link[MAX/2];
    bool dfs(int u){
        for(int i = head[u]; i != -1; i = edge[i].next){
            int v = edge[i].to;
            if(!useif[v]){
                useif[v] = true;
                if(link[v] == -1 || dfs(link[v]))
                {
                    link[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    void match(){
        int ans_num = 0;
        memset(link,-1,sizeof(link));
        for(int i = 1; i <= node_num; i ++){
            memset(useif,false,sizeof(useif));
            if(dfs(i)) ans_num++;
        }
    
        //print
        cout << ans_num/2 <<endl;
        bool ifmatch[MAX/2]={false}; //这里是表示这个点是不是被输出过
        for(int i = 1; i <= node_num; i ++){
            if(!ifmatch[i] && link[i] != -1 && !ifmatch[link[i]]){
                ifmatch[i] = true; ifmatch[link[i]] = true;
                printf("(%d,%d)--(%d,%d)
    ",loc[i][0],loc[i][1],loc[link[i]][0],loc[link[i]][1]);
            }
        }
    }
    
    int main()
    {
        bool first_cas = true;//控制案例间空行
        while(cin >> N >> M)
        {
            if(!N && !M) break;
            cin >> K;
            initMap();
            if(!first_cas) cout << endl;
            match();
            first_cas = false;
        }
        return 0;
    }
    
    个人愚昧观点,欢迎指正与讨论

  • 相关阅读:
    解决electron-vue中无法使用Element的Tooltip组件
    解决Electron安装包下载慢的问题
    虚拟机VirtualBox 共享挂载问题:mount: /mnt/xxx: wrong fs type, bad option, bad superblock on xxx
    git 设置和取消代理
    (转载)数据库连接池到底应该设多大?这篇文章可能会颠覆你的认知
    MySQL主主复制+MMM实现高可用
    Mysql5.6主从热备配置
    java 启动 shell脚本
    redis批量删除key
    spring mvc异常统一处理(ControllerAdvice注解)
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5066994.html
Copyright © 2020-2023  润新知