1. 程式人生 > 實用技巧 >HDU 1281 最大匹配+重要點計數

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); } }