zoukankan      html  css  js  c++  java
  • hdu 3468(二分匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3468

    大牛思路:

    用BFS找出每一个集合点到其它可达点的距离以及这个集合点到下一集合点的距离

    枚举是否能从一个集合点K经过一个宝物点X到达下一个集合点(K+1).如果能的话,则path[K][X]=true;

     如果发现有一个集合点不可达的话,则输出-1;

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 #define MAXN 110
      8 char map[MAXN][MAXN];
      9 int dd[MAXN];//保存相邻集合点之间的距离
     10 int dist[MAXN][MAXN*MAXN];//保存集合点到图中任意一点之间的距离
     11 bool mark[MAXN*MAXN];
     12 bool path[MAXN][MAXN*MAXN];//标记二部图x与y的连通性
     13 int match[MAXN*MAXN];//匹配
     14 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
     15 int n,m,p,q;
     16 
     17 int GetId(char ch){
     18     if(ch>='A'&&ch<='Z')return ch-'A';
     19     return ch-'a'+26;
     20 }
     21 
     22 void bfs(int x,int y,int id){
     23     queue<int>Q;
     24     Q.push(x),Q.push(y);
     25     dist[id][x*m+y]=0;
     26     while(!Q.empty()){
     27         x=Q.front();Q.pop();
     28         y=Q.front();Q.pop();
     29         int d=dist[id][x*m+y];
     30         for(int i=0;i<4;i++){
     31             int xx=x+dir[i][0];
     32             int yy=y+dir[i][1];
     33             if(xx>=0&&xx<n&&yy>=0&&yy<m&&map[xx][yy]!='#'&&dist[id][xx*m+yy]==-1){
     34                 dist[id][xx*m+yy]=d+1;
     35                 Q.push(xx),Q.push(yy);
     36                 if(isalpha(map[xx][yy])&&(GetId(map[xx][yy])==id+1)){
     37                     dd[id]=d+1;
     38                 }
     39             }
     40         }
     41     }
     42 }
     43 
     44 
     45 
     46 bool dfs(int k,int m){
     47     for(int i=0;i<m;i++){
     48         if(path[k][i]&&!mark[i]){
     49             mark[i]=true;
     50             if(match[i]==-1||dfs(match[i],m)){
     51                 match[i]=k;
     52                 return true;
     53             }
     54         }
     55     }
     56     return false;
     57 }
     58 
     59 
     60 int Hungary(int n,int m){
     61     int ans=0;
     62     memset(match,-1,sizeof(match));
     63     for(int i=0;i<n;i++){
     64         memset(mark,false,sizeof(mark));
     65         if(dfs(i,m))ans++;
     66     }
     67     return ans;
     68 }
     69 
     70 
     71 int main(){
     72     while(~scanf("%d%d",&n,&m)){
     73         memset(dist,-1,sizeof(dist));
     74         memset(dd,-1,sizeof(dd));
     75         memset(path,false,sizeof(path));
     76         p=q=0;
     77         for(int i=0;i<n;i++){
     78             scanf("%s",map[i]);
     79         }
     80         for(int i=0;i<n;i++){
     81             for(int j=0;j<m;j++){
     82                 if(isalpha(map[i][j])){
     83                     p=max(p,GetId(map[i][j]));
     84                     bfs(i,j,GetId(map[i][j]));
     85                 }
     86             }
     87         }
     88         bool flag=true;
     89         for(int i=0;i<p;i++){
     90             if(dd[i]==-1){ flag=false;break; }
     91         }
     92         if(!flag){ puts("-1");continue; }
     93         for(int i=0;i<n;i++){
     94             for(int j=0;j<m;j++){
     95                 if(map[i][j]=='*'){
     96                     for(int k=0;k<p;k++){
     97                         //判断金子是否在最短路上
     98                         if(dist[k][i*m+j]+dist[k+1][i*m+j]==dd[k]){
     99                             path[k][q]=true;
    100                         }
    101                     }
    102                     q++;
    103                 }
    104             }
    105         }
    106         printf("%d\n",Hungary(p+1,q));
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    EELS
    企业管理软件随想透视>包容,无形思想>有形方便
    定风波
    企业管理软件随想也谈企业框架软件需求
    Delphi数据库开发-前言
    游戏引发的……
    js 当前时间
    代码片段
    阶段总结
    Web界面设计
  • 原文地址:https://www.cnblogs.com/wally/p/3089138.html
Copyright © 2011-2022 走看看