您的位置:首页 > 其它

HDU1281 棋盘游戏(坐标平面 ,行列匹配+求关键点)

2015-08-15 18:01 519 查看
题意:略;

思路:把坐标X看做二分图的左边,Y看做右边,结合二分图的最大匹配,左右顶点形成的最大匹配边,就是不同行不同列。求关键点,就依次枚举删掉某一个边后是否会使匹配变小

#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#include<set>
#include<stack>
#define cl(a,b) memset(a,b,sizeof(a));
#define LL long long
#define P pair<int,int>
#define X first
#define Y second
#define pb push_back
using namespace std;
const int maxn=150;
const int inf=9999999;
const int mod=100007;
int G[maxn][maxn];
int x[maxn*maxn],y[maxn*maxn];
int matching[maxn];
bool vis[maxn];
int n,m,k;
bool dfs(int u){
for(int i=0;i<m;i++)if(G[u][i]){
int v=i;
if(vis[v])continue;
vis[v]=true;
if(matching[v]==-1||dfs(matching[v])){
matching[v]=u;
return true;
}
}
return false;
}
int hungar(){
int ans=0;
cl(matching,-1);
for(int i=0;i<n;i++){
cl(vis,false);
if(dfs(i))ans++;
}
return ans;
}

int main(){
int cas=1;
while(~scanf("%d%d%d",&n,&m,&k)){
cl(G,0);
for(int i=0;i<k;i++){
scanf("%d%d",&x[i],&y[i]);
x[i]--;y[i]--;
G[x[i]][y[i]]=1;
}

int ans=0;
int mx=hungar();
// printf("===%d\n",mx);
for(int i=0;i<k;i++){
G[x[i]][y[i]]=0;//删除
if(hungar()<mx)ans++;
G[x[i]][y[i]]=1;//复原
}
printf("Board %d have %d important blanks for %d chessmen.\n",cas++,ans,mx);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: