HDU 1281 最大匹配+重要点计数

xg

题意

  给了一个矩阵,其中k个点可以放“车”。不同车不能放同一行和同一列。

  求最大匹配和重要点的个数。重要点为,若这个点不放点,则就不能放尽可能多的车。

思路

  最大匹配好求。为ans。

  重要点的个数,对于这k个点。第i个点不存在的话,若最大匹配sum小于ans,则该点为重要点。

  

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <vector> 

#define bug cout<<"--------------"<<endl
#define sp ' '
using namespace std;
typedef long long ll;

const int maxn = 2e4+10;
std::vector<int> e[maxn];
struct node 
{
    int x,y;
}cun[maxn];
int n,m,k,l,r;
int vis[maxn],match[maxn];
bool dfs(int x)
{
    //for(int i = head[x],y;i; i = nextt[i])
    for(auto y : e[x]){
        if(x == l && r == y) continue;    
        if(!vis[y]){
            vis[y] = 1;
            if(!match[y] || dfs(match[y])){
                match[y] = x; return 1;
            }
        }
    }
    return 0;
}
int a[maxn],cnt[maxn];
void clearr()
{
    l = 0,r = 0;
    for(int i = 1;i <= 20000 ;++i){
        e[i].clear();
    }
    memset(match,0,sizeof(match));
    memset(cnt,0,sizeof(cnt));

}
int main()
{
    //freopen("input.txt", "r", stdin); 
    int casee = 0;
    while(scanf("%d%d%d",&n,&m,&k) != EOF){
        clearr();
        for(int i =1 ;i <=k;++i){
            scanf("%d%d",&cun[i].x,&cun[i].y);
            cun[i].y += n;
            e[cun[i].x].push_back(cun[i].y);
            //e[cun[i].y].push_back(cun[i].x);
        }
        int ans =0;
        for(int i = 1;i <= n+m;++i){
            memset(vis,0,sizeof(vis));
            if(dfs(i)){
                ans++;
            } 
        } 
        int sum = 0;
        for(int t = 1;t <= k;++t){
            int tmp = 0;
             l = cun[t].x,r = cun[t].y;
            memset(match,0,sizeof(match));
            for(int i = 1;i <= n+m;++i){
                memset(vis,0,sizeof(vis));
                if(dfs(i)){
                    tmp++;
                } 
            }      
            //cout<<tmp<<endl;       
            if(tmp != ans){
                sum++;
            }
        }
        printf("Board %d have %d important blanks for %d chessmen.\n",++casee,sum,ans);
    }
}

 

posted @ 2020-08-24 10:31  阿斯水生产线  阅读(79)  评论(0编辑  收藏  举报