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 }
  • 相关阅读:
    ClickOnce發布經驗
    reporting Server組件不全引起的致命錯誤
    異步調用
    Usercontrol Hosted in IE
    MATLAB命令大全(转载)
    一种保护眼睛的好方法
    关于oracle自动编号
    An Algorithm Summary of Programming Collective Intelligence (1)
    An Algorithm Summary of Programming Collective Intelligence (3)
    An Algorithm Summary of Programming Collective Intelligence (4)
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7800909.html
Copyright © 2011-2022 走看看