hdu 1281 棋盘游戏 最大匹配(经典题)
2013-09-07 15:50
267 查看
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> #include <iostream> using namespace std; const int maxn=101; int e[maxn][maxn]; int vis[maxn],pre[maxn]; int n,m,k,a[maxn],b[maxn]; int find(int u)//判断增广路是否存在 { int i,j,v; for(v=1;v<=n;v++) { if(!vis[v]&&e[u][v]) { vis[v]=1; if(pre[v]==-1||find(pre[v])) { pre[v]=u; return 1; } } } return 0; } int work() { int i,j,ans=0; memset(pre,-1,sizeof(pre)); for(i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); ans+=find(i); } return ans; } int main() { int tt=0; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { int i,j; memset(e,0,sizeof(e)); for(i=1;i<=k;i++) { scanf("%d%d",&a[i],&b[i]); e[a[i]][b[i]]=1; } int ans,num=0; ans=work(); for(i=1;i<=k;i++) { e[a[i]][b[i]]=0; if(work()!=ans) num++; e[a[i]][b[i]]=1; } printf("Board %d have %d important blanks for %d chessmen.\n",++tt,num,ans); } return 0; } /* 最大匹配:在图G中,找出边数最多的子图M,使得M中每条边都没有公共顶点。则M就是G的最大匹配 匈牙利算法:通过计算增广路数求最大匹配。 二分图左右点集代表图的横纵坐标 本题中,边表示的是棋盘中所处的位置,由于车可以攻击在同行和同列上的目标,而题意是找出最多的棋子数, 使得各个棋子不能相互攻击。即在图找出最多的边,使得各个边都没有公共顶点(二分图中左右顶点集编号相同的点 认为是不同的顶点)。这根最大匹配的定义相同,所以求最大匹配即可。 而重要点就是去掉这个棋盘点对应的边,最大匹配值改变,则这个棋盘点就是重要点。 */
相关文章推荐
- HDU 1281 棋盘游戏(最大二分匹配)
- hdu 1281 棋盘游戏 (二分图最大匹配)
- hdu 1281 棋盘游戏(枚举,二分图最大匹配)
- HDU_1281 棋盘游戏 (二分图的最大匹配)
- hdu 1281 棋盘游戏(最大匹配·匈牙利)
- HDU 1281 棋盘游戏 二分图最大匹配 + 枚举
- HDU 1281 棋盘游戏(二分图最大匹配:关键边)
- HDU 1281 — 棋盘游戏 最大匹配
- hdu 1281 棋盘游戏 二分图最大匹配
- hdu 1281 棋盘游戏(匈牙利(最大匹配+枚举))
- hdu 1281 棋盘游戏 二分图最大匹配
- hdu1281 棋盘游戏 (最大匹配)
- hdu 1281 棋盘游戏 (最大匹配,重要点)
- hdu 1281 棋盘游戏(最大匹配)
- HDU 1281 棋盘游戏(匈牙利算法 二分最大匹配)
- HDU 1281 棋盘游戏(二分图最大匹配:关键边)
- [HDU 1281] 棋盘游戏 最大匹配
- HDU 1281 棋盘游戏 最大匹配+枚举
- HDU 1281 棋盘游戏 二分图的最大匹配
- HDU 1281 棋盘游戏 (二分图的最大匹配)