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 } 
  • 相关阅读:
    网络安全分析
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1540 机器
    java实现 洛谷 P1540 机器
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/3809620.html
Copyright © 2011-2022 走看看