hdu 1281 棋盘游戏

http://acm.hdu.edu.cn/showproblem.php?pid=1281

题意:一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下。但是某些格子若不放子,就无法保证放尽量多的“车”,这样的格子被称做重要点。算出有多少个这样的重要点。

思路:题目没有说出要严格每个车合占一行和一列。先求出最大可放的车数目ans。然后枚举每个位置不放车的情况下,可放车的最大数目tans,如果tans<ans,则计数cnt++。

        实在很难想像这么度复杂度的也能过。试过n=m=100,as[n][m]=1情况下,3s+才出结果~~~

View Code
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<bitset>
#include<string>
#include<climits>
#include<cstdio>
#include<vector>
#include<utility>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define IN puts("in")
#define OUT puts("out")
#define FR(x) freopen(x,"r",stdin)
#define FW(x) freopen(x,"w",stdout)
#define MSET(x,y) memset(x,y,sizeof(x))
#define ST system("pause")
#define lowbit(x) (x)&(-x)
#define L(x) (x)<<1
#define R(x) ((x)<<1)^1
using namespace std;
const int maxn = 105;
int as[maxn][maxn],vis[maxn],to[maxn];
int n,m;
int dfs(int u)
{
        for(int v = 1; v <= m; ++ v)
                if(as[u][v]&&!vis[v]){
                        vis[v] = 1;
                        if(to[v]==0||dfs(to[v])){
                                to[v] = u;
                                return 1;
                        }
                }
        return 0;
}
int maxmatch()
{
        int i,cnt=0;
        MSET(to,0);
        for(i = 1; i <= n; ++ i){
                MSET(vis,0);
                cnt+=dfs(i);
        }return cnt;
}
int main()
{
        int i,j,k,ans,cnt,cas=0;
        while(scanf("%d %d %d",&n,&m,&k)==3)
        {
                MSET(as,0);
                for(i = 0; i < k; ++ i){
                        int x,y;
                        scanf("%d %d",&x,&y);
                        as[x][y] = 1;
                }
                ans = maxmatch();
                cnt = 0;
                for(i = 1; i <= n; ++ i)
                        for(j = 1; j<= m; ++ j)if(as[i][j]){
                                as[i][j] = 0;
                                if(maxmatch()<ans)cnt++;
                                as[i][j] = 1;
                        }
                printf("Board %d have %d important blanks for %d chessmen.\n",++cas,cnt,ans);
        }
        return 0;
}

 

 

posted on 2012-07-23 16:22  aigoruan  阅读(208)  评论(0)    收藏  举报

导航