HDU 1281 最大匹配+重要點計數
阿新 • • 發佈:2020-08-24
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); } }