POJ 2195 最小费用流

来源:互联网 发布:webform做数据库分页 编辑:程序博客网 时间:2024/06/01 17:20

题目链接

 第一次做最小费用流的问题,之前一直是盲点。

从这道题来看,我对最小费用最大流的理解是,在最大流约束的条件下,每次寻找可行路都找费用最小的那一条,做若干次最短路,直到最后没有增广路。

这道题点的总数可达到202,第一次交题的时候没注意,导致RE


#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<vector>#include<cmath>#include<queue>#include<map>#define lson node<<1,l,l+r>>1#define rson node<<1|1,(l+r>>1)+1,r#define INF 0x3f3f3f3fusing namespace std;typedef long long LL;const int _maxNodes = 1e5+10;struct Node{    int x, y;    Node(){}    Node(int u, int v){        x = u; y = v;    }};Node man[210], house[210];int n,m;char graph[210][210];int num_m, num_h;int source, sink;int cost[210][210], d[210][210];int parent[210];bool vis[210];int mincost[210];int ans;void init(){    for (int i = 0; i < n; i++){        scanf("%s", graph[i]);    }    num_m = num_h = 0;    for (int i = 0; i < n; i++){        for (int j = 0; j < m; j++){            if (graph[i][j] == 'H'){                house[++num_h] = Node(i, j);            }            else if (graph[i][j] == 'm'){                man[++num_m] = Node(i, j);            }        }    }    source =  0; sink = num_m + num_h + 1;    memset(cost,0,sizeof cost);    memset(d,0,sizeof d);    for (int i = 1; i <= num_m; i++){        d[source][i] = 1;    }    for (int i = 1; i <= num_m; i++){        for (int j = 1; j <= num_h; j++){            d[i][num_m+j] = 1;            cost[i][num_m+j] = abs(man[i].x - house[j].x) + abs(man[i].y - house[j].y);            cost[num_m+j][i] = -cost[i][num_m+j];        }    }    for (int i = 1; i <= num_h; i++){        d[num_m+i][sink] = 1;    }}void SPFA(){    queue<int> que;    int v, i;    memset(vis,false,sizeof(vis));    memset(parent,-1,sizeof (parent));    for (i = source; i <= sink; i++) mincost[i] = INF;    que.push(source);    mincost[source] = 0;    vis[source] = true;    while (!que.empty()){        v = que.front(); que.pop();        vis[v] = false;        for (i = source; i <= sink; i++){            if (d[v][i] && mincost[v] + cost[v][i] < mincost[i]){                mincost[i] = mincost[v] + cost[v][i];                parent[i] = v;                if (!vis[i]){                    que.push(i);                    vis[i] = true;                }            }        }    }}void solve(){    int v;    ans = 0;    while (1){        SPFA();        if (parent[sink] == -1) break;        v = sink;        while (parent[v] != -1){            d[parent[v]][v] -= 1;            d[v][parent[v]] += 1;            v = parent[v];        }        ans += mincost[sink];    }    printf("%d\n",ans);}int main(){    while (scanf("%d %d",&n, &m) == 2){        if (n == 0 && m == 0) break;        init();        solve();    }    return 0;}


0 0
原创粉丝点击