hdu1281(二分图)

来源:互联网 发布:excel怎么对比数据 编辑:程序博客网 时间:2024/06/06 16:31

题目链接:棋盘游戏

题目大意:给定一个n*m的棋盘,其中k个格子可以放车(车可以横着走和竖着走即攻击,不限步数),要求同一行或者同一列不能放多余一辆车。如果去掉一个位置的车,所能放的最多车的数目减少,就称为重要点,求重要点的个数。

题目分析:典型的行列匹配题,由于某行或某列最多放一个车,当某点放车时,该点的行和列之间就连一条边,边数就是能放的最多的车数。

                    暴力解法:每次去掉一个点,即去掉一条边,重新计算匹配数(最多的车数),如变少,则该点就是重要点。

                    复杂度:O(E*V^2)


#include <stdio.h>#include <memory.h>const int maxn=105;bool vis[maxn];int g[maxn][maxn],link[maxn];int n,m,k;int dfs(int u){    for(int v=1;v<=m;v++){        if(g[u][v]&&!vis[v]){            vis[v]=true;            if(link[v]==-1||dfs(link[v])){                link[v]=u;                return 1;            }        }    }    return 0;}int hungry(){    int cnt=0;    memset(link,-1,sizeof(link));    for(int u=1;u<=n;u++){        memset(vis,0,sizeof(vis));        cnt+=dfs(u);    }    return cnt;}int main(){    //freopen("in.txt","r",stdin);    int x[maxn*maxn],y[maxn*maxn];    int T=1;    while(scanf("%d %d %d",&n,&m,&k)!=EOF){        memset(g,0,sizeof(g));        int import=0;        for(int i=0;i<k;i++){            scanf("%d %d",&x[i],&y[i]);            g[x[i]][y[i]]=1;        }        int ans=hungry();        for(int i=0;i<k;i++){            g[x[i]][y[i]]=0;            int tmp=hungry();            if(tmp<ans)import++;1;            g[x[i]][y[i]]=1;        }        printf("Board %d have %d important blanks for %d chessmen.\n",T++,import,ans);    }    return 0;}


0 0
原创粉丝点击