HDU-1281 棋盤遊戲
阿新 • • 發佈:2018-12-16
把每行看作一點,每列看作一點,可以放置的格子就是邊,連線其所在行和列兩點
那麼用二分圖最大匹配很容易就求出來,最多可以放置多少車
然後對於每個給出的格子,在求一次沒有這個格子的最大匹配,如果小於原來的匹配,說明這是重要的格子
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long ll; const int N=100+10; const int M=1e4+10; bool g[N][N]; int linker[N]; bool used[N]; int n,m,k; bool dfs(int u) { for(int i=1;i<=m;i++) { if(used[i]||!g[u][i]) continue; used[i]=true; if(linker[i]==-1||dfs(linker[i])) { linker[i]=u; return true; } } return false; } int hungary() { int res=0; memset(linker,-1,sizeof(linker)); for(int i=1;i<=n;i++) { memset(used,false,sizeof(used)); if(dfs(i)) res++; } return res; } int a[M],b[M]; int main() { int kase=0; while(~scanf("%d%d%d",&n,&m,&k)) { memset(g,false,sizeof(g)); for(int i=0;i<k;i++) { scanf("%d%d",&a[i],&b[i]); g[a[i]][b[i]]=true; } int num=hungary(); int ans=0; for(int i=0;i<k;i++) { g[a[i]][b[i]]=false; if(hungary()<num) ans++; g[a[i]][b[i]]=true; } printf("Board %d have %d important blanks for %d chessmen.\n",++kase,ans,num); } return 0; }