poj Going Home

來源:互聯網
上載者:User

標籤:style   blog   io   os   ar   for   sp   2014   on   

                               Going Home

 

題目:

   給出一個N*M的圖,圖上的m表示人,H表示房子,每座房子只能有一個人,要求你所有人到房子中總步數最少。m個數與H個數一樣多。

 

演算法分析:

   這個題目還是比較裸的。可以想到先求出每個人到每座房子的距離。然後求出最小花費,這個好像就是最小費用流吧?一開始用了KM寫完後,發現。。。。哪裡不對啊?後來才覺悟,原來題目是求解最小花費,KM是最大匹配下最大權值。。。。。

 

#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <map>#include <cstdio>#include <cstring>using namespace std;typedef pair<int,int> P;const int INF = 1 << 20;const int MAXN = 400 + 10;///////////////////////////////最小費用struct Edge{    int to,cap,cost,rev;    Edge(){};    Edge(int _to,int _cap,int _cost,int _rev)        :to(_to),cap(_cap),cost(_cost),rev(_rev){};};vector<Edge> G[MAXN];int V;int h[MAXN];int dist[MAXN];int prevv[MAXN],preve[MAXN];int src,sink;/////////////////////////////////////////尋找距離struct Point{   int x,y,dis;   Point(){};   Point(int _x,int _y,int _dis)        :x(_x),y(_y),dis(_dis){};};vector<Point> cost;map<int,int> mp;int N,M,cnt1,cnt2;char str[MAXN][MAXN];int dirx[5] = {-1,1,0,0};int diry[5] = {0,0,-1,1};int W[MAXN][MAXN],ans[MAXN];int slack,Lx[MAXN],Ly[MAXN],Link[MAXN];bool S[MAXN],T[MAXN];////////////////////////////////////bool check(int x,int y){   if(x >= 0&& x < N&&y >=0 && y < M)      return true;   return false;}void bfs(int s,int e){     bool vst[MAXN][MAXN];     memset(vst,0,sizeof(vst));     queue <Point> que;     que.push(Point(s,e,0));     vst[s][e] = 1;     while(!que.empty()){          Point pv = que.front(); que.pop();          for(int i = 0;i < 4;++i){             Point tmp;             tmp.x = pv.x + dirx[i];             tmp.y = pv.y + diry[i];             tmp.dis = pv.dis + 1;             if(check(tmp.x,tmp.y)&&!vst[tmp.x][tmp.y]){                vst[tmp.x][tmp.y] = 1;                if(str[tmp.x][tmp.y] == 'H'){                    int num = tmp.x * N + tmp.y;                    if(mp.count(num) == 0){                        mp[num] = ++cnt2;                    }                    cost.push_back(Point(cnt1,mp[num],tmp.dis));                }                que.push(tmp);             }          }     }}////bool Match(int i){//    S[i] = true;//    for(int j = 1;j <= cnt2;++j)if(!T[j]){//        int tmp =   Lx[i] + Ly[j] - W[i][j];//        if(tmp == 0){//            T[j] = true;//            if(Link[j] == -1||Match(Link[j])){//                Link[j] = i;//                return true;//            }//        }//        else if(tmp < slack)//            slack = tmp;//    }//    return false;//}////void update(int d){//   for(int i = 1;i <= cnt1;++i)//      if(S[i]) Lx[i] -= d;//   for(int i = 1;i <= cnt2;++i)//      if(T[i]) Ly[i] += d;//}////bool EK(){//   for(int i = 1;i <= cnt1;++i){//       Link[i] = -1;//       Lx[i] = Ly[i] = 0;//       for(int j = 1;j <= cnt2;++j)//          Lx[i] = max(Lx[i],W[i][j]);//   }////   slack = INF;////   for(int i = 1;i <= cnt1;++i){//      for(;;){//        memset(S,false,sizeof(S));//        memset(T,false,sizeof(T));//        if(Match(i))//            break;////        if(slack == INF)//            return false;//        update(slack);//      }////   }//   return true;//}////int getAns(){//   int sum = 0;//   for(int j = 1;j <= cnt2;++j){//       if(Link[j] != -1)//         sum += W[Link[j]][j];//   }//   return sum;//}void addEdge(int from,int to,int cap,int cost){    G[from].push_back(Edge(to,cap,cost,G[to].size()));    G[to].push_back(Edge(from,0,-cost,G[from].size() - 1));}int min_cost_flow(int s,int t,int f){   int res = 0;   V = sink + 1;   fill(h,h + V,0);   while(f > 0){       priority_queue<P,vector<P>,greater<P> > que;       fill(dist,dist + V,INF);       dist[s] = 0;       que.push(P(0,s));       while(!que.empty()){           P p = que.top(); que.pop();           int v = p.second;           if(dist[v] < p.first) continue;           for(int i = 0;i < (int)G[v].size();++i){               Edge& e = G[v][i];               int tmp = dist[v] + e.cost + h[v] - h[e.to];               if(e.cap > 0 && dist[e.to] > tmp){                    dist[e.to] = tmp;                    prevv[e.to] = v;                    preve[e.to] = i;                    que.push(P(dist[e.to],e.to));               }           }       }       if(dist[t] == INF){           return -1;       }       for(int v = 1;v < V;++v) h[v] += dist[v];       int dd = f;       for(int v = t;v != s ;v = prevv[v]){          dd = min(dd,G[prevv[v]][preve[v]].cap);       }       f -= dd;       res += dd * h[t];       for(int v = t;v != s;v = prevv[v]){          Edge& e = G[prevv[v]][preve[v]];          e.cap -= dd;          G[v][e.rev].cap += dd;       }   }   return res;}void init(){    for(int i = 0;i <= sink;++i)        G[i].clear();}void solve(){   cnt1 = 0;   cnt2 = 0;   mp.clear();   cost.clear();   //尋找距離   for(int i = 0;i < N;++i){     for(int j = 0;j < M;++j){         if(str[i][j] == 'm'){            cnt1++;            bfs(i,j);         }     }   }   Point tmp;   for(int i = 0;i < (int)cost.size();++i){       tmp = cost[i];       W[tmp.x][tmp.y] = tmp.dis;   }   //建圖   V = cnt1 + cnt2;   src = V + 1; sink = src + 1;   init();   for(int i = 1;i <= cnt1;++i){     //m      for(int j = 1;j <= cnt2;++j){  //H          addEdge(i,j + cnt1,1,W[i][j]);      }   }   for(int i = 1;i <= cnt1;++i){       addEdge(src,i,1,0);   }   for(int i = 1;i <= cnt2;++i){              //!!!!!!!! 變點的時候一定要注意啊!      addEdge(cnt1 + i,sink,1,0);   }   int res = min_cost_flow(src,sink,cnt1);   printf("%d\n",res);}int main(){    //freopen("Input.txt","r",stdin);    while(scanf("%d%d",&N,&M),(N||M)){        for(int i = 0;i < N;++i){            scanf("%s",str[i]);        }        solve();    }    return 0;}


 

poj Going Home

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.