hdu_3360 National Treasures 最小点覆盖

来源:互联网 发布:windows启动盘下载 编辑:程序博客网 时间:2024/06/05 05:00
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;#define N 52int dx[13]={-1,-2,-2,-1,1,2,2,1,-1,0,1,0};int dy[13]={-2,-1,1,2,2,1,-1,-2,0,1,0,-1};int edge[N][N];vector<int> g[N*N];int linker[N*N];bool vis[N*N];int hash1[N][N];struct node{int x,y;int val;}s[N*N];bool dfs(int u){for(int i=0;i<g[u].size();i++){int v=g[u][i];if(!vis[v]){vis[v]=1;if(linker[v]==-1||dfs(linker[v])){linker[v]=u;return true;}}}return false;}int hungary(int n){memset(linker,-1,sizeof(linker));int cnt=0;for(int i=0;i<n;i++){memset(vis,0,sizeof(vis));if(dfs(i)) cnt++;}return cnt;}int main(){int n,m,f=1;while(scanf("%d%d",&n,&m)!=EOF){if(!n&&!m) break;for(int i=1;i<=n*m;i++)g[i].clear();memset(hash1,-1,sizeof(hash1));int ans=0;int x;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&x);edge[i][j]=x;if(x==-1) continue;s[ans].val=x;s[ans].x=i;s[ans].y=j;hash1[i][j]=ans;ans++;}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){for(int h=0;h<12;h++){int k=edge[i][j]&(1<<h);if(k==0) continue;if(edge[i][j]==-1) continue;int tx=i+dx[h];int ty=j+dy[h];if(tx<1||ty<1||tx>n||ty>m) continue;if(edge[tx][ty]==-1) continue;g[hash1[i][j]].push_back(hash1[tx][ty]);g[hash1[tx][ty]].push_back(hash1[i][j]);}}}printf("%d. %d\n",f++,hungary(ans)/2);}return 0;}

求最小点覆盖=二分图最大匹配

刚开始超时了,用两个循环枚举i=0-ans进行相连判断;果断超时,最后用hash记录每个二维坐标的id,枚举坐标,解决问题!!

原创粉丝点击