HDU1507二分图

Uncle Tom‘s Inherited Land*

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3445    Accepted Submission(s): 1452
Special Judge

Problem Description

Your old uncle Tom inherited a piece of land from his great-great-uncle. Originally, the property had been in the shape of a rectangle. A long time ago, however, his great-great-uncle decided to divide the land into a grid of small squares. He turned some of the squares into ponds, for he loved to hunt ducks and wanted to attract them to his property. (You cannot be sure, for you have not been to the place, but he may have made so many ponds that the land may now consist of several disconnected islands.)

Your uncle Tom wants to sell the inherited land, but local rules now regulate property sales. Your uncle has been informed that, at his great-great-uncle‘s request, a law has been passed which establishes that property can only be sold in rectangular lots the size of two squares of your uncle‘s property. Furthermore, ponds are not salable property.

Your uncle asked your help to determine the largest number of properties he could sell (the remaining squares will become recreational parks). 

Input

Input will include several test cases. The first line of a test case contains two integers N and M, representing, respectively, the number of rows and columns of the land (1 <= N, M <= 100). The second line will contain an integer K indicating the number of squares that have been turned into ponds ( (N x M) - K <= 50). Each of the next K lines contains two integers X and Y describing the position of a square which was turned into a pond (1 <= X <= N and 1 <= Y <= M). The end of input is indicated by N = M = 0.

Output

For each test case in the input your program should first output one line, containing an integer p representing the maximum number of properties which can be sold. The next p lines specify each pair of squares which can be sold simultaneity. If there are more than one solution, anyone is acceptable. there is a blank line after each test case. See sample below for clarification of the output format.

Sample Input

4 4

6

1 1

1 4

2 2

4 1

4 2

4 4

4 3

4

4 2

3 2

2 2

3 1

0 0

Sample Output

4
(1,2)--(1,3)
(2,1)--(3,1)
(2,3)--(3,3)
(2,4)--(3,4)

3
(1,1)--(2,1)
(1,2)--(1,3)
(2,3)--(3,3)

Source

South America 2002 - Practice

题意:n*m的网格,有的不能用,要求相邻的两个小方格为一组,问最多有多少组。

代码:

//简单的二分匹配,相邻的且可用的网格之间建边,求玩=完二分图之后link数组存储的就是答案。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int vis[10004],link[10004],nu1[10004],nu2[10004],pond[10004];
int Mu,Mv,n,m,k,last;
vector<int>g[10004];
bool dfs(int x)
{
    for(int i=0;i<g[x].size();i++){
        int y=g[x][i];
        if(!vis[y]){
            vis[y]=1;
            if(link[y]==-1||dfs(link[y])){
                link[y]=x;
                return 1;
            }
        }
    }
    return 0;
}
int Maxcon()
{
    int ans=0;
    memset(link,-1,sizeof(link));
    for(int i=1;i<=n*m;i++){
        if(pond[i]) continue;
        memset(vis,0,sizeof(vis));
        if(dfs(i)) ans++;
    }
    return ans;
}
int main()
{
    while(scanf("%d%d",&n,&m)&&(n+m)){
        int x,y;
        memset(pond,0,sizeof(pond));
        scanf("%d",&k);
        while(k--){
            scanf("%d%d",&x,&y);
            pond[(x-1)*m+y]=1;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                int id=(i-1)*m+j;
                g[id].clear();
                if(i>1&&pond[id-m]==0) g[id].push_back(id-m);
                if(j>1&&pond[id-1]==0) g[id].push_back(id-1);
                if(i<n&&pond[id+m]==0) g[id].push_back(id+m);
                if(j<m&&pond[id+1]==0) g[id].push_back(id+1);
            }
        }
        int ans=Maxcon()/2;
        printf("%d\n",ans);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                int id=(i-1)*m+j;
                if(link[id]==-1||link[link[id]]==-1) continue;
                printf("(%d,%d)--(%d,%d)\n",i,j,(link[id]-1)/m+1,link[id]%m==0?m:link[id]%m);
                link[id]=link[link[id]]=-1;
            }
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-10-06 11:20:59

HDU1507二分图的相关文章

HDU1507 Uncle Tom&#39;s Inherited Land* 二分图匹配 匈牙利算法 黑白染色

原文链接http://www.cnblogs.com/zhouzhendong/p/8254062.html 题目传送门 - HDU1507 题意概括 有一个n*m的棋盘,有些点是废的. 现在让你用1*2的矩形覆盖所有的不废的点,并且不重叠,问最多可以覆盖多少个1*2的矩形,输出方案,有SPJ. 输入描述: 多组数据,每组首先两个数n,m(如果n和m为0,则结束程序) 然后给出k 然后给出k个二元组(x,y)表示废点的坐标. 题解 按照前两片博文的算法已经不行了,因为方案不对了. 所以我们要进行

HDU1507 Uncle Tom&#39;s Inherited Land*

题目是跟 zoj1516是一样的,但多了匹配后的输出 详解zoj1516可见http://www.cnblogs.com/CSU3901130321/p/4228057.html 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 using namespace std; 5 6 const int maxn = 55; 7 int n , m , k; 8 int g[maxn][maxn] ,

bzoj4025 二分图

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4025 [题解] 考虑对时间分治,用可撤回的启发式合并并查集来维护连通性. 二分图的条件是没有奇环,用并查集判即可. 对于时间区间[l,r],如果边在这期间都存在,那么就加入并查集,对于剩下的边分类,并且分治下去做. 对于每条边,在log个区间表示出来了,需要进行判断,启发式合并的getf是log的,所以复杂度为O(nlog^2n) # include <stdio.h> # includ

POJ2584 T-Shirt Gumbo 二分图匹配(网络流)

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int inf=0x3f3f3f3f; 6 const int sink=30; 7 8 struct Edge 9 { 10 int to; 11 int next; 12 int capacity; 13 14 void assign(int t,int n,int c) 15 { 16 to=t; next=n; ca

棋盘游戏(二分图匹配)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1281 棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3200    Accepted Submission(s): 1897 Problem Description 小 希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放

二分图【模板】

二分图:原图G的顶点可以分类两个集合X和Y,所有的边关联的两个顶点恰好一个属于集合X,另一个属于集合Y,则称该图为二分图. 二分图匹配:给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,即一个顶点最多只有一条边.则称M是一个匹配. 二分图最大匹配:图中包含边数最多的匹配称为图的最大匹配. 二分图完美匹配:如果所有点都在匹配边上,则称这个最大匹配是完美匹配. 二分图多重匹配:二分图匹配一对一匹配,这里允许集合Y中的一个元素和集合X中的多个元素匹配(一般有最大限制N)

NYOJ 237 游戏高手的烦恼 &amp;&amp; POJ3041-Asteroids ( 二分图的最大匹配 )

链接: NYOJ 237  游戏高手的烦恼:click here~~ POJ  3041 Asteroids           :click here~~ 题意: 两题一样,翻译不同而已. 有一位传说级游戏高手,在闲暇时间里玩起了一个小游戏,游戏中,一个n*n的方块形区域里有许多敌人,玩家可以使用炸弹炸掉某一行或者某一列的所有敌人.他是种玩什么游戏都想玩得很优秀的人,所以,他决定,使用尽可能少的炸弹炸掉所有的敌人. 现在给你一个游戏的状态,请你帮助他判断最少需要多少个炸弹才能炸掉所有的敌人吧.

POJ1325 Machine Schedule 【二分图最小顶点覆盖】

Machine Schedule Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11958   Accepted: 5094 Description As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduli

HDU 1045 Fire Net 二分图Bipartite题解

本题可以使用DFS直接爆搜出答案,不过这样类型的题目其实是个二分图的题解. 这个二分图,难不在Hungary算法,而是难在于建图.需要挺高的抽象思维的. 建图: 1 把同一行不被X分开的格子标同一个号码,被X分开的标下一个号码,这样做是为了缩点,不需要把所有的格子都分开标号,而且可以更方便建个更加小的图. 2 同理把同一列的格子标号 3 然后判断相同一个格子的行标号和列标号是有路径的,其他不在同一个格子的都是没有路径的. 4 这样就等于以行标号和列标号作为左右顶点,构建成一个二分图了 然后使用H