zoukankan      html  css  js  c++  java
  • POJ2195-Going Home

    传送门

    题目大意:给定一些人和一些房子,人和房子一样多,求配对。配对代价就是人和房子的距离

    思路:这是一个二分图的模型,带权二分图用KM算法即可

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<queue>
      6 #define MAXN 105
      7 #define pii pair<int,int>
      8 #define INF 0x7f7f7f7f
      9 using namespace std;
     10 int X,Y;
     11 int n;
     12 int G[MAXN][MAXN];
     13 char s[MAXN][MAXN];
     14 vector<pii> va,vb;
     15 int a[MAXN][MAXN];
     16 int b[MAXN][MAXN];
     17 int d[5]={0,1,0,-1,0};
     18 int bfs(int t){
     19     memset(b,0,sizeof(b));
     20     queue<pair<pii,int> > q;
     21     q.push(make_pair(va[t-1],0));
     22     b[va[t-1].first][va[t-1].second]=1;
     23     while(!q.empty()){
     24         int x=q.front().first.first,y=q.front().first.second;
     25         int L=q.front().second;
     26         q.pop();
     27         for(int k=0;k<4;k++){
     28             int dx=x+d[k],dy=y+d[k+1];
     29             if(1<=dx&&dx<=X&&1<=dy&&dy<=Y&&!b[dx][dy]){
     30                 b[dx][dy]=L+1;
     31                 q.push(make_pair(make_pair(dx,dy),L+1));
     32                 if(a[dx][dy]){
     33                     G[t][a[dx][dy]]=-(L+1);
     34                 }    
     35             }
     36         }
     37     }     
     38 }
     39 void init(){
     40     memset(G,0,sizeof(G));
     41     memset(a,0,sizeof(a));
     42     va.clear();
     43     vb.clear();
     44     n=0;
     45     for(int i=1;i<=X;i++){
     46         scanf("%s",s[i]+1);
     47         for(int j=1;j<=Y;j++){
     48             if('m'==s[i][j]){
     49                 va.push_back(make_pair(i,j));
     50                 n++;
     51             }
     52             else if('H'==s[i][j]){
     53                 vb.push_back(make_pair(i,j));
     54                 a[i][j]=vb.size();
     55             }
     56         }    
     57     }    
     58     for(int i=1;i<=n;i++){
     59         bfs(i);
     60     }    
     61 }
     62 int vis_v1[MAXN],vis_v2[MAXN];
     63 int ex_v1[MAXN],ex_v2[MAXN];
     64 int match[MAXN],slack[MAXN];
     65 int dfs(int x){
     66     vis_v2[x]=1;
     67     for(int i=1;i<=n;i++){
     68         if(vis_v1[i]){
     69             continue;
     70         }
     71         int gap=ex_v1[i]+ex_v2[x]-G[x][i];
     72         if(!gap){
     73             vis_v1[i]=1;
     74             if(!match[i]||dfs(match[i])){
     75                 match[i]=x;
     76                 return 1;
     77             }
     78         }
     79         else{
     80             slack[i]=min(slack[i],gap);
     81         }
     82     }    
     83     return 0;
     84 }
     85 int KM(){
     86     memset(match,0,sizeof(match));
     87     memset(ex_v1,0,sizeof(ex_v1));
     88     for(int i=1;i<=n;i++){
     89         ex_v2[i]=G[i][1];
     90         for(int j=2;j<=n;j++){
     91             ex_v2[i]=max(ex_v2[i],G[i][j]);
     92         }    
     93     }
     94     for(int i=1;i<=n;i++){
     95         memset(slack,0x7f,sizeof(slack));
     96         while(1){
     97             memset(vis_v1,0,sizeof(vis_v1));
     98             memset(vis_v2,0,sizeof(vis_v2));
     99 
    100             if(dfs(i)) break;
    101 
    102             int d=INF;
    103             for(int j=1;j<=n;j++){
    104                 if(!vis_v1[j]){//!!!
    105                     d=min(d,slack[j]);
    106                 }
    107             }
    108             for(int j=1;j<=n;j++){
    109                 if(vis_v2[j]){
    110                     ex_v2[j]-=d;
    111                 }
    112                 if(vis_v1[j]){
    113                     ex_v1[j]+=d;
    114                 }
    115                 else{
    116                     slack[j]-=d;
    117                 }
    118             }
    119         }
    120     }    
    121     int ans=0;
    122     for(int i=1;i<=n;i++){
    123         ans-=G[match[i]][i];
    124     }
    125     return ans;
    126 }
    127 void solve(){
    128     printf("%d
    ",KM());
    129 }
    130 int main()
    131 {
    132 //    freopen("data.in","r",stdin);
    133     while(1){
    134         scanf("%d%d",&X,&Y);
    135         if(!X&&!Y){
    136             break;
    137         }
    138         init();
    139         solve();
    140     }    
    141     return 0;
    142 }
  • 相关阅读:
    中国区 Azure 服务和定价模式概述
    云计算的那些「What」
    【虚拟机-可用性集】ARM 中可用性集使用的注意事项
    【虚拟机-可用性集】将虚拟机添加到可用性集中
    【虚拟机-远程连接】Azure Linux 虚拟机常见导致无法远程的操作
    【虚拟机-远程链接】Azure Windows 虚拟机常见导致无法远程的操作
    【虚拟机-网络IP】使用 Powershell 设置 VNET 中的静态 IP
    matlab的diff()函数
    matlab的拟合函数polyfit()函数
    解决Python各种no module named "XX"的问题
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7800909.html
Copyright © 2011-2022 走看看