HDU 1281 棋盘游戏
题解:将所有的横坐标看作一边的点,纵坐标看作另一边的点,然后二分图匹配即可,建图很巧妙……
#include <cstdio> #include <cstring> #define maxn 105 bool map[maxn][maxn],vis[maxn]; int n,m,k,mark[maxn],edge[maxn*maxn][2]; bool dfs(int v){ for(int i=1;i<=m;i++){ if(vis[i]||!map[i][v]) continue; vis[i]=true; if(mark[i]==0||dfs(mark[i])){ mark[i]=v; return true; } } return false; } int Hungarian(){ int count=0; memset(mark,0,sizeof(mark)); for(int i=1; i<=n; i++){ memset(vis,false,sizeof(vis)); if(dfs(i)) count++; } return count; } int main(){ int i,sum,num=1; while(scanf("%d%d%d",&n,&m,&k)!=EOF){ memset(map,false,sizeof(map)); for(i=0;i<k;i++){ scanf("%d%d",&edge[i][0],&edge[i][1]); map[edge[i][0]][edge[i][1]] = true; } int max=Hungarian(); for(i=sum=0;i<k;i++){ map[edge[i][0]][edge[i][1]]=false; if(max>Hungarian()) sum++; map[edge[i][0]][edge[i][1]]=true; } printf("Board %d have %d important blanks for %d chessmen.\n",num++,sum,max); } return 0; }
愿你出走半生,归来仍是少年