前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HDU 1281 棋盘游戏(二分图最大匹配+枚举删边)

HDU 1281 棋盘游戏(二分图最大匹配+枚举删边)

作者头像
Ch_Zaqdt
发布2019-01-11 11:03:10
4780
发布2019-01-11 11:03:10
举报
文章被收录于专栏:Zaqdt_ACM

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1281

       题意很难理解...其实就是问最多能放多少个车,然后我们把这个放车的点删去,看会不会影响最大能放车的值,如果能影响,这个点就是一个important点,思路就是我们先将图按行和列分成两个集合求一个二分图最大匹配(裸的匈牙利),然后我们枚举每条边进行删除操作,然后用当前的最大匹配数和之前的最大匹配数比较,不同则就是一个important点。


AC代码:

代码语言:javascript
复制
#include <bits/stdc++.h>
#define maxn 205
using namespace std;
int edge[maxn][maxn];
int pre[maxn];
bool vis[maxn];
int x[maxn], y[maxn];
int n,m,k;

bool dfs(int x){
  for(int i=1;i<=m;i++){
    if(vis[i] == false && edge[x][i]){
      vis[i] = true;
      if(pre[i] == -1 || dfs(pre[i])){
        pre[i] = x;
        return true;
      }
    }
  }
  return false;
}

int main()
{
  int Case = 1;
  while(~scanf("%d%d%d",&n,&m,&k)){
    memset(edge,0,sizeof(edge));
    for(int i=1;i<=k;i++){
      scanf("%d%d",&x[i],&y[i]);
      edge[ x[i] ][ y[i] ] = 1;
    }
    int ans = 0;
    int cnt = 0;
    memset(pre,-1,sizeof(pre));
    for(int i=1;i<=n;i++){
      memset(vis,false,sizeof(vis));
      if(dfs(i)) ans ++;
    }
    for(int i=1;i<=k;i++){
      edge[ x[i] ][ y[i] ] = 0;
      memset(pre,-1,sizeof(pre));
      int ans1 = 0;
      for(int j=1;j<=n;j++){
        memset(vis,false,sizeof(vis));
        if(dfs(j)) ans1 ++;
      }
      if(ans1 != ans) cnt ++;
      edge[ x[i] ][ y[i] ] = 1;
    }
    printf("Board %d have %d important blanks for %d chessmen.\n",Case++,cnt,ans);
  }
  return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年11月08日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档