zoukankan      html  css  js  c++  java
  • poj 2195(最小费用流)

    题意:一个矩阵中不同位置给出n个人,和n个房子,求解n个人分别回到n个房子的最小时间花费。

    思路:最大权匹配,可用最小费用流,km算法求解。

    最小费用流算法:

    View Code
      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<algorithm>
      5 using namespace std;
      6 #define inf 0x3f3f3f3f
      7 #define N 100010
      8 #define M N*10
      9 struct edge{
     10     int a,next,b,cap,flow,cost;
     11 }e[M];
     12 struct point{
     13     int x,y;
     14 }m[N],h[N];
     15 int pre[N],q[N*2],in[N],low[N],dist[N],p[N];
     16 int cnt,S,T;
     17 void add(int a,int b,int cap,int cost)
     18 {
     19     edge es={a,pre[a],b,cap,0,cost};
     20     e[cnt]=es;
     21     pre[a]=cnt++;
     22 }
     23 bool spfa()
     24 {
     25     int rear=0,tail=1;
     26     q[0]=S;
     27     memset(low,0,sizeof(low));
     28     memset(in,0,sizeof(in));
     29     for(int i=S;i<=T;i++)
     30     dist[i]=inf;
     31     low[S]=inf;dist[S]=0;
     32     in[S]=1;
     33     while(rear<tail)
     34     {
     35         int u=q[rear++];
     36         in[u]=0;
     37         for(int edg=pre[u];edg!=0;edg=e[edg].next)
     38         {
     39             int v=e[edg].b;
     40             if(dist[v]>dist[u]+e[edg].cost&&e[edg].cap>e[edg].flow)
     41             {
     42                 p[v]=edg;
     43                 dist[v]=dist[u]+e[edg].cost;
     44                 if(!in[v]){
     45                     q[tail++]=v;
     46                     in[v]=1;
     47                 }
     48                 low[v]=min(low[u],e[edg].cap-e[edg].flow);
     49                 if(v==T)break;
     50             }
     51         }
     52     }
     53     return low[T]!=0;
     54 }
     55 int dfs()
     56 {
     57     int tf=0;
     58     while(spfa())
     59     {
     60         tf+=low[T]*dist[T];
     61         for(int x=p[T];x!=0;x=p[e[x].a])
     62         {
     63             e[x].flow+=low[T];
     64             e[x^1].flow-=low[T];
     65         }
     66     }
     67     return tf;
     68 }
     69 int main()
     70 {
     71     int r,c;
     72     while(scanf("%d%d",&r,&c)!=EOF)
     73     {
     74         memset(pre,0,sizeof(pre));
     75         cnt=2;
     76         int hc=1,mc=1;
     77         if(r==0&&c==0)break;
     78         for(int i=1;i<=r;i++)
     79         {
     80             getchar();
     81             for(int j=1;j<=c;j++)
     82             {
     83                 char ch;
     84                 scanf("%c",&ch);
     85                 if(ch=='m'){
     86                     m[mc].x=i;
     87                     m[mc++].y=j;
     88                 }
     89                 else if(ch=='H')
     90                 {
     91                     h[hc].x=i;
     92                     h[hc++].y=j;
     93                 }
     94             }
     95         }
     96         S=0;T=mc+hc-1;
     97         for(int i=1;i<mc;i++)
     98         for(int j=1;j<hc;j++)
     99         {
    100             int len=abs(m[i].x-h[j].x)+abs(m[i].y-h[j].y);
    101             add(i,j+mc-1,1,len);
    102             add(j+mc-1,i,0,-len);
    103         }
    104         for(int i=1;i<mc;i++)
    105         {
    106             add(S,i,1,0);
    107             add(i,S,0,0);
    108         }
    109         for(int i=1;i<hc;i++)
    110         {
    111             add(i+mc-1,T,1,0);
    112             add(T,i+mc-1,0,0);
    113         }
    114         printf("%d\n",dfs());
    115     }
    116 }

     KM算法实现:

    View Code
     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<algorithm>
     5 using namespace std;
     6 #define inf 0x3f3f3f3f
     7 #define N 1010
     8 int d;
     9 int net[N][N],x[N],y[N],lx[N],ly[N],link[N];
    10 struct point{
    11     int x,y;
    12 }m[N],h[N];
    13 bool dfs(int u,int mc)
    14 {
    15     x[u]=1;
    16     for(int v=1;v<mc;v++)
    17     {
    18         if(y[v])continue;
    19         int t=lx[u]+ly[v]-net[u][v];
    20         if(!t)
    21         {
    22             y[v]=1;
    23             if(!link[v]||dfs(link[v],mc))
    24             {
    25                 link[v]=u;
    26                 return true;
    27             }
    28         }
    29         else d=min(d,t);
    30     }
    31     return false;
    32 }
    33 int km(int mc,int hc)
    34 {
    35     memset(ly,0,sizeof(ly));
    36     for(int i=0;i<mc;i++)
    37     lx[i]=inf;
    38     for(int i=1;i<mc;i++)
    39     {
    40         while(1)
    41         {
    42             d=inf;
    43             memset(x,0,sizeof(x));
    44             memset(y,0,sizeof(y));
    45             if(dfs(i,mc))break;
    46             for(int j=1;j<mc;j++)
    47             {
    48                 if(x[j])lx[j]-=d;
    49                 if(y[j])ly[j]+=d;
    50             }
    51         }
    52     }
    53     int sum=0;
    54     for(int i=1;i<mc;i++)
    55     sum+=lx[i]+ly[i];
    56     return sum;
    57 }
    58 int main()
    59 {
    60     int r,c;
    61     while(scanf("%d%d",&r,&c))
    62     {
    63         if(r==0&&c==0)break;
    64         int mc=1,hc=1;
    65         for(int i=1;i<=r;i++)
    66         {
    67             getchar();
    68             for(int j=1;j<=c;j++)
    69             {
    70                 char ch;
    71                 scanf("%c",&ch);
    72                 if(ch=='m')
    73                 {
    74                     m[mc].x=i;
    75                     m[mc++].y=j;
    76                 }
    77                 else if(ch=='H')
    78                 {
    79                     h[hc].x=i;
    80                     h[hc++].y=j;
    81                 }
    82             }
    83         }
    84         memset(net,0,sizeof(net));
    85         memset(link,0,sizeof(link));
    86         for(int i=1;i<mc;i++)
    87         {
    88             for(int j=1;j<hc;j++)
    89             {
    90                 net[i][j]=500-(abs(m[i].x-h[j].x)+abs(m[i].y-h[j].y));
    91             }
    92         }
    93         printf("%d\n",500*(mc-1)-km(mc,hc));
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    浅浅地聊一下矩阵与线性映射及矩阵的特征值与特征向量
    再谈正态分布或高斯函数
    喜好:
    Deep Residual Learning for Image Recognition这篇文章
    Java并发编程:volatile关键字解析
    mysql decimal(10,2)对应java类型
    各个JSON技术的比较(Jackson,Gson,Fastjson)的对比
    @RequestBody和@RequestParam区别
    Java中的ReentrantLock和synchronized两种锁定机制的对比
    使用Solr索引MySQL数据
  • 原文地址:https://www.cnblogs.com/huangriq/p/2482668.html
Copyright © 2011-2022 走看看