POJ 2195 Going Home 最小费用最大流 尼玛,心累

D - Going Home

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status Practice POJ 2195

Appoint description:

Description

On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically, to an adjacent point. For each little man, you need to pay a $1 travel fee for every step he moves, until he enters a house. The task is complicated with the restriction that each house can accommodate only one little man.

Your task is to compute the minimum amount of money you
need to pay in order to send these n little men into those n different
houses. The input is a map of the scenario, a ‘.‘ means an empty space,
an ‘H‘ represents a house on that point, and am ‘m‘ indicates there is a
little man on that point.


You
can think of each point on the grid map as a quite large square, so it
can hold n little men at the same time; also, it is okay if a little man
steps on a grid with a house without entering that house.

Input

There are one or more test cases in the input. Each case starts with a
line giving two integers N and M, where N is the number of rows of the
map, and M is the number of columns. The rest of the input will be N
lines describing the map. You may assume both N and M are between 2 and
100, inclusive. There will be the same number of ‘H‘s and ‘m‘s on the
map; and there will be at most 100 houses. Input will terminate with 0 0
for N and M.

Output

For each test case, output one line with the single integer, which is the minimum amount, in dollars, you need to pay.

Sample Input

2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0

Sample Output

2
10
28

尼玛心累啊,为什么从源点链接房子,在链接人在链接会点jiu不行,,,,,,必须按照源点---》ren---》房子,,,,会点的顺序建图还有数组额外注意,尼玛了,因为数组开小,wa了14个小时,,,,,
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=10005;
const int maxm=20505;
const int inf=0x3f3f3f3f;
struct Edge{
   int to;
   int next;
   int cap,flow,cost;
}edge[maxm];
int head[maxn],tot;
int pre[maxn],dis[maxn];
bool vis[maxn];
int n;
char str[500];
struct node{
  int x,y;

}p[maxn],q[maxn];

void init(int nn){
    n=nn;
    tot=0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int cap,int cost){
   edge[tot].to=v;
   edge[tot].cap=cap;
   edge[tot].cost=cost;
   edge[tot].flow=0;
   edge[tot].next=head[u];
   head[u]=tot++;
    edge[tot].to=u;
   edge[tot].cap=0;
   edge[tot].cost=-cost;
   edge[tot].flow=0;
   edge[tot].next=head[v];
   head[v]=tot++;
}
bool spfa(int s,int t){
      queue<int >q;
//    printf("n====%d\n",n);
    for(int i=0;i<=n;i++){
         dis[i]=inf;
         vis[i]=false;
         pre[i]=-1;
    }
    dis[s]=0;
    vis[s]=true;
    q.push(s);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
               dis[v]=dis[u]+edge[i].cost;
               pre[v]=i;
               if(!vis[v]){
                  vis[v]=true;
                  q.push(v);
               }

            }
        }

    }
    if(pre[t]==-1)
        return false;
    else
        return true;

}
int mincost(int s,int t,int &cost){
      int flow=0;
      cost=0;
    //  printf("%d\n",head[2]);
      while(spfa(s,t)){
          int Min=inf;
        for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){
            if(Min>edge[i].cap-edge[i].flow)
                Min=edge[i].cap-edge[i].flow;
        }
        for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){
                edge[i].flow+=Min;
                edge[i^1].flow-=Min;
                cost+=edge[i].cost*Min;

        }
        flow+=Min;

      }

//      printf("cost=====%d  flow======%d\n",cost,flow);
      return flow;
}

int main(){
     int x,y;
     while(scanf("%d%d",&x,&y)!=EOF){
             if(x==0&&y==0)
                 break;
             n=x*y+1;
             init(n);
             int start=0;
             int end=n;
             int pp=0,qq=0;
             for(int i=1;i<=x;i++){
                   scanf("%s",str+1);
                 for(int j=1;j<=y;j++){
                      int cnt=(i-1)*y+j;
                      if(str[j]==‘m‘){
                         addedge(start,cnt,1,0);
                         p[pp].x=i;
                         p[pp++].y=j;
                      }
                      if(str[j]==‘H‘){
                         addedge(cnt,end,1,0);
                         q[qq].x=i;
                         q[qq++].y=j;
                      }
                }
            //     printf("%s\n",str+1);
             }

             for(int i=0;i<pp;i++){
                 for(int j=0;j<qq;j++){
                     addedge((p[i].x-1)*y+p[i].y,(q[j].x-1)*y+q[j].y,1,abs(p[i].x-q[j].x)+abs(p[i].y-q[j].y));
                 }
             }
         int tmp;
            int ans=mincost(start,end,tmp);
            printf("%d\n",tmp);

     }
     return 0;
}
5634445 qwerqqq D
Accepted
1188 110
G++
2650
5 min ago
5634440 qwerqqq D
Wrong Answer
   
G++
2650
5 min ago
5634430 qwerqqq D
Accepted
1188 125
G++
2650
6 min ago
5634424 qwerqqq D
Accepted
1188 110
G++
2654
7 min ago
5634358 qwerqqq D
Accepted
1188 125
G++
2654
12 min ago
5634345 qwerqqq D
Accepted
1192 110
G++
2654
12 min ago
5634339 qwerqqq D
Accepted
1188 110
G++
2655
12 min ago
5634334 qwerqqq D
Accepted
1228 110
G++
2655
13 min ago
5634307 qwerqqq D
Accepted
1540 110
G++
2656
16 min ago
5634289 qwerqqq D
Wrong Answer
   
G++
2651
17 min ago
5634263 qwerqqq D
Time Limit Exceeded
   
C++
2647
19 min ago
5634250 qwerqqq D
Wrong Answer
   
G++
2647
21 min ago
5634209 qwerqqq D
Wrong Answer
   
G++
3005
24 min ago
5634202 qwerqqq D
Time Limit Exceeded
   
C++
3005
24 min ago
5631907 qwerqqq D
Wrong Answer
   
G++
2662
14 hr ago
时间: 2024-12-28 14:54:24

POJ 2195 Going Home 最小费用最大流 尼玛,心累的相关文章

POJ 2195 Going Home (最小费用最大流)

题目链接:http://poj.org/problem?id=2195 题意:n*m的矩阵,地图上有若干个人(m)和房子(H),且人与房子的数量一致.man每移动一格费用为1,一个房子只能住一个人.现在要求所有的人出发,都入住房子,求最少话费. 思路:建立一个超级源点和汇点,源点与人相连费用为0,容量为1,人与房子相连,费用为人与房子的距离,容量为1,房子与汇点相连,费用为0,容量为1 #include <iostream> #include <cstdlib> #include

POJ 2195 地图的最小费用最大流

思路:这题刚开始看就知道是最小费用最大流了,因为求出最优嘛,而且要m,H要一一对应,所以不是二分图匹配就是最小费用最大流. 不过,刚开始还在想每个m与H之间的最小花费如何求,难道要用dfs搜索吗?这样想之后看了下题目给的时间是1000ms,然后就把dfs搜索m与H之间的最短距离排除了.然后想了想,其实尼玛太简单了,因为题目说了只能垂直与竖直的走,所以最短距离不就是两个横坐标相减与两个纵坐标相减之和嘛! 然后每对m与H之间都连边,流量为1(因为每对匹配不能重复),费用为它们之间的距离即花费:然后建

POJ 2195 - Going Home - [最小费用最大流][MCMF模板]

题目链接:http://poj.org/problem?id=2195 Time Limit: 1000MS Memory Limit: 65536K Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically, to an adjacent

POJ 2516 Minimum Cost(最小费用最大流,坑题)

题目链接:http://poj.org/problem?id=2516 题意:有N个店,M个供货商,K种商品.已知供货商的仓库里每种商品的数量以及每种商品运送到每个店的费用,每个店铺对各种商品的需求数量,求最少话费. Input  第一行:N,M,K. 然后1 - N行,每行 K列 ,第I行第J个数代表 第I个店铺 需要第J种物品多少件. 然后 N+1 - M行  ,每行 K列 , 第I行第J个数代表 第I个供货商 有第J种物品多少件. 然后是K个矩阵  ,每个N行M列,第ji个矩阵的第i行第j

POJ 2516 Minimum Cost (最小费用最大流)

Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K       Description Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his sale area there are N shopkeepers (marked from 1 to N) which stocks goods from him.Dearboy

POJ 3680: Intervals【最小费用最大流】

题目大意:你有N个开区间,每个区间有个重量wi,你要选择一些区间,使得满足:每个点被不超过K个区间覆盖的前提下,重量最大 思路:感觉是很好想的费用流,把每个区间首尾相连,费用为该区间的重量的相反数(由于要最大,所以是求最大费用最大流),容量为1,至于不超过K的限制,只要从源点到第一个点的流量为K就行,剩下每个相邻的点相连,费用为0,流量只要大于的等于K就可以(我取的正无穷) //poj3680 #include <stdio.h> #include <iostream> #incl

POJ 2135 Farm Tour [最小费用最大流]

题意: 有n个点和m条边,让你从1出发到n再从n回到1,不要求所有点都要经过,但是每条边只能走一次.边是无向边. 问最短的行走距离多少. 一开始看这题还没搞费用流,后来搞了搞再回来看,想了想建图不是很难,因为要保证每条边只能走一次,那么我们把边拆为两个点,一个起点和终点,容量是1,权重是这条路的长度.然后两个端点分别向起点连接容量是1权重是0的边,终点分别向两个端点连容量是1权重是0的边,从源点到1连容量为2权重为0的边,从n到汇点连容量为2权重为0的边. #include<stdio.h>

POJ 2195:Going Home(最小费用最大流)

http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大流.最小费用最大流是保证在流量最大的情况下,使得费用最小. 建图是把S->人->家->T这些边弄上形成一个网络,边的容量是1(因为一个人只能和一个家匹配),边的费用是曼哈顿距离,反向边的费用是-cost. 算法的思想大概是通过SPFA找增广路径,并且找的时候费用是可以松弛的.当找到这样一条增

poj 2195 最小费用最大流模板

/*Source Code Problem: 2195 User: HEU_daoguang Memory: 1172K Time: 94MS Language: G++ Result: Accepted Source Code */ #include <iostream> #include <stdio.h> #include <queue> #include <math.h> #include <string.h> using namespa