zoukankan      html  css  js  c++  java
  • poj 2195 Going Home

      1 /*
      2    做网络流的题建图真的是太重要了!
      3    本题是将人所在的位置和房子所在的位置建立边的联系,其中man到house这一条边的流量为 1, 费用为两者的距离
      4    而方向边的流量为 0, 费用为正向边的相反数(也就是沿着反向边进行增广时,费用要减少,更改先前错误的选择) 
      5    最后增加一个源点和一个汇点完毕(源点映射到man, house映射到汇点, 费用为0, 流量为1) 
        
    6 */ 7 #include<iostream> 8 #include<cmath> 9 #include<cstdio> 10 #include<cstring> 11 #include<queue> 12 #define Max 0x3f3f3f3f 13 #define N 205 14 using namespace std; 15 16 class node 17 { 18 public: 19 int x, y; 20 }; 21 22 node xyM[N]; 23 node xyH[N]; 24 int cost[N][N], cap[N][N]; 25 int cntM, cntH; 26 int pre[N*2], dist[N*2], vis[N*2], n, m; 27 28 void addE(int i, int j, int ct, int cp) 29 { 30 cost[i][j]=ct; 31 cap[i][j]=cp; 32 cost[j][i]=-ct; 33 //cap[j][i]=0; 34 } 35 36 int s, t, minCost; 37 38 void buildMap() 39 { 40 int i, j; 41 memset(cap, 0, sizeof(cap)); 42 s=0; t=cntM+cntH+1; 43 for(i=0; i<cntM; ++i) 44 addE(0, i+1, 0, 1); 45 for(i=0; i<cntH; ++i) 46 addE(cntM+i+1, t, 0, 1); 47 for(i=0; i<cntM; ++i) 48 for(j=0; j<cntH; ++j) 49 addE(i+1, cntM+j+1, abs(xyM[i].x-xyH[j].x)+abs(xyM[i].y-xyH[j].y), 1); 50 } 51 52 queue<int>q; 53 54 int spfa() 55 { 56 int u, v; 57 memset(dist, 0x3f, sizeof(dist)); 58 dist[0]=0; 59 q.push(0); 60 vis[0]=1; 61 while(!q.empty()) 62 { 63 u=q.front(); 64 q.pop(); 65 vis[u]=0; 66 for(v=0; v<=t; ++v) 67 if(cap[u][v]>0 && dist[v]>dist[u]+cost[u][v]) 68 { 69 dist[v]=dist[u]+cost[u][v]; 70 pre[v]=u; 71 if(!vis[v]) 72 { 73 vis[v]=1; 74 q.push(v); 75 } 76 } 77 } 78 if(dist[t]==Max) 79 return 0; 80 return 1; 81 } 82 83 void updateEdge() 84 { 85 int u, minFlow=Max; 86 for(u=t; u!=s; u=pre[u])//通过最短路径寻找这条路径上的最小流量 87 if(cap[pre[u]][u]<minFlow) 88 minFlow=cap[pre[u]][u]; 89 for(u=t; u!=s; u=pre[u]) 90 { 91 cap[pre[u]][u]-=minFlow; 92 cap[u][pre[u]]+=minFlow; 93 minCost+=cost[pre[u]][u]; 94 } 95 } 96 97 int main() 98 { 99 int i, j; 100 char c; 101 while(scanf("%d%d", &n, &m) && (n||m)) 102 { 103 cntM=cntH=0; 104 minCost=0; 105 for(i=1; i<=n; ++i) 106 { 107 getchar(); 108 for(j=1; j<=m; ++j) 109 { 110 scanf("%c", &c); 111 if(c=='m') 112 { 113 xyM[cntM].x=i; 114 xyM[cntM++].y=j; 115 } 116 else if(c=='H') 117 { 118 xyH[cntH].x=i; 119 xyH[cntH++].y=j; 120 } 121 } 122 } 123 buildMap(); 124 while(spfa()) 125 updateEdge(); 126 printf("%d ", minCost); 127 } 128 return 0; 129 }

     //邻接表

      1 #include<iostream>
      2 #include<queue>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #define INF 0x3f3f3f3f
      7 #define N 1000005
      8 using namespace std;
      9 
     10 int cntH, cntM;
     11 
     12 struct node{
     13     int x, y;
     14 };
     15 
     16 struct EDGE{
     17     int u, v, cap, cost, nt;
     18 };
     19 EDGE edge[N];
     20 
     21 queue<int>q;
     22 node man[105], house[105];
     23 int first[205];
     24 int dist[205];
     25 int pre[205], flow[205], vis[205];
     26 int cnt, t;
     27 int minCost;
     28 int n, m;
     29 
     30 void addEdge(int u, int v, int cap, int cost){
     31     edge[cnt].u=u;
     32     edge[cnt].v=v;
     33     edge[cnt].cap=cap;
     34     edge[cnt].nt=first[u];
     35     edge[cnt].cost=cost;
     36     first[u]=cnt++;
     37     
     38     edge[cnt].u=v;
     39     edge[cnt].v=u;
     40     edge[cnt].cap=0;
     41     edge[cnt].nt=first[v];
     42     edge[cnt].cost=-cost;
     43     first[v]=cnt++;
     44 }
     45 
     46 void buildMap(){
     47     memset(first, -1, sizeof(first));
     48     t=cntH+cntM+1;
     49     for(int i=1; i<=cntM; ++i)
     50         for(int j=1; j<=cntH; ++j)
     51             addEdge(i, cntM+j, 1, abs(man[i].x-house[j].x) + abs(man[i].y-house[j].y));
     52     for(int i=1; i<=cntM; ++i)
     53         addEdge(0, i, 1, 0);
     54     for(int i=1; i<=cntH; ++i)
     55         addEdge(cntM+i, t, 1, 0); 
     56 }
     57 
     58 bool MCMF(){
     59     memset(dist, 0x3f, sizeof(dist));
     60     memset(vis, 0, sizeof(vis));
     61     q.push(0);
     62     flow[0]=INF;
     63     dist[0]=0;
     64     vis[0]=1;
     65     while(!q.empty()){
     66         int u=q.front(); q.pop();
     67         vis[u]=0;
     68         for(int e=first[u]; ~e; e=edge[e].nt){
     69             int v=edge[e].v, cap=edge[e].cap, cost=edge[e].cost;
     70             if(cap>0 && dist[v]>dist[u]+cost){
     71                 dist[v]=dist[u]+cost;
     72                 flow[v]=min(flow[u], cap);
     73                 pre[v]=e;
     74                 if(!vis[v]){
     75                     vis[v]=1;
     76                     q.push(v);
     77                 }
     78             }
     79         }
     80     }
     81     if(dist[t]==INF) return false;
     82     minCost+=dist[t];
     83     int x=t;
     84     while(x!=0){
     85         edge[pre[x]].cap-=flow[t];
     86         edge[pre[x]^1].cap+=flow[t];
     87         x=edge[pre[x]].u;
     88     }
     89     return true;
     90 }
     91  
     92 int main(){
     93     while(scanf("%d%d", &n, &m) && (n||m)){
     94         cnt=cntH=cntM=0;
     95         for(int i=1; i<=n; ++i){
     96             getchar();
     97             for(int j=1; j<=m; ++j){
     98                 char ch;
     99                 scanf("%c", &ch);
    100                 if(ch=='m'){
    101                     man[++cntM].x=i;
    102                     man[cntM].y=j;
    103                 }
    104                 else if(ch=='H'){
    105                     house[++cntH].x=i;
    106                     house[cntH].y=j;
    107                 }
    108             }
    109         }
    110         buildMap();
    111         minCost=0;
    112         while(MCMF());
    113         printf("%d
    ", minCost);
    114     }
    115     return 0;
    116 } 
  • 相关阅读:
    git下载指定的版本
    QT中定时器
    makefile 中添加依赖的库文件
    Qt 出现“undefined reference to `vtable for”
    qt程序启动播放动画
    常用正则表达式
    当你纠结时,请打开这31个锦…
    android mk详解
    C++日志系统log4cxx使用总结
    qt 坐标变换
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/3809620.html
Copyright © 2011-2022 走看看