hdu1281+坐标构图+二分匹配

来源:互联网 发布:杭州宏杉科技 知乎 编辑:程序博客网 时间:2024/05/22 13:12

hdu1281+坐标构图+二分匹配

这道题主要就是构图思想 之前的hdu1045题也是一样的 但是没想明白为什么这样构图是正确的
虽然说现在也没真正想清楚 但是也能够进一步理解
解题思路是 以x 和 y轴建立二分图 x和y分别代表两个集合 如果一个点可以放车 那么x,y连一条边
因为是 坐标的垂直方向和水平方向不能有车 所以这个坐标x,y连一条边,这样就可以排除车相互攻击的可能性 代表可以放东西
这是一个新思想 可以好好的斟酌

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream> #include<stdio.h>#include<vector>#include<queue>#include<string.h>#include<algorithm>#define inf 0x3f3f3f3fusing namespace std;const int Maxn=305;const int Maxm=1000005;int head[Maxn],tot,linker[Maxn],colour[Maxn],k,m,n,u,v;;bool used[Maxn],g[Maxn][Maxn];bool dfs2(int u){for(int i=1;i<=n;i++)if(g[u][i] && !used[i]){used[i]=true;if(linker[i]==-1 || dfs2(linker[i])){linker[i]=u;return true;}}return false;}int pipei(){int ans=0;memset(linker,-1,sizeof(linker));for(int i=1;i<=n;i++){memset(used,0,sizeof(used));if(dfs2(i))//因为是每个点都遍历 所以不用考虑图的联通性 ans++;}return ans;} int main(){int ca=0;while(scanf("%d%d%d",&n,&m,&k)!=EOF){memset(g,0,sizeof(g));        for(int i=0;i<k;i++)        {scanf("%d%d",&u,&v);g[u][v]=true;//只能是单向 因为两个集合下标是一样的 }int ans=pipei(),cnt=0;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(g[i][j]){g[i][j]=0;if(ans!=pipei()) cnt++;g[i][j]=1;}}printf("Board %d have %d important blanks for %d chessmen.\n",++ca,cnt,ans);}return 0; } 


0 0
原创粉丝点击