POJ 2112 — Optimal Milking 网络流+floyd+二分

来源:互联网 发布:java的tostring方法 编辑:程序博客网 时间:2024/06/16 06:59

原题:http://poj.org/problem?id=2112

题意:

有k个挤奶器,c头牛,每个挤奶器可以服务m头牛;

给出[k+c, k+c]的矩阵,表示任意两点间的距离(0表示无法到达)

问使得所有牛都能被服务的最短距离;


思路:

先用floyd求出最短距离;

再二分这些距离,只要距离小于等于该值就可建边,然后判断最大流是否等于c;

最后输出最小值;


#include<stdio.h>#include<queue>#include<string.h>#include<vector>#include<iostream>#include<algorithm>#define inf 1e9const int maxn = 1500;using namespace std;int k, c, m;int dis[maxn][maxn];struct Edge{    int from, to, cap, flow;    Edge(){}    Edge(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl){}};int head[maxn], edgenum;struct Dinic{    int n, m, s, t;    vector<Edge>edges;    vector<int>G[maxn];    bool vis[maxn];    int cur[maxn];    int d[maxn];    void init(int n, int s, int t)    {        this->n = n, this->s = s, this->t = t;        edges.clear();        for(int i = 0;i<n;i++) G[i].clear();    }    void add(int from, int to, int cap)    {        edges.push_back( Edge(from, to, cap, 0) );        edges.push_back( Edge(to, from, 0, 0) );        m = edges.size();        G[from].push_back(m-2);        G[to].push_back(m-1);    }    bool BFS()    {        queue<int>q;        memset(vis, false, sizeof(vis));        vis[s] = true;        d[s] = 0;        q.push(s);        while(!q.empty())        {            int x = q.front(); q.pop();            for(int i = 0;i<G[x].size();i++)            {                Edge& e = edges[G[x][i]];                if(!vis[e.to] && e.cap>e.flow)                {                    vis[e.to] = true;                    d[e.to] = d[x]+1;                    q.push(e.to);                }            }        }        return vis[t];    }    int DFS(int x, int a)    {        if(x==t || a==0) return a;        int flow = 0, f;        for(int &i = cur[x];i<G[x].size();i++)        {            Edge &e = edges[G[x][i]];            if(d[e.to] == d[x]+1 && (f = DFS(e.to,min(a,e.cap-e.flow)))>0)            {                e.flow+=f;                edges[G[x][i]^1].flow-=f;                flow+=f;                a-=f;                if(a == 0) break;            }        }        return flow;    }    int maxflow()    {        int ans = 0;        while(BFS())        {            memset(cur, 0, sizeof(cur));            ans+=DFS(s, inf);        }        return ans;    }}DC;int main(){while(scanf("%d%d%d", &k, &c, &m)!=EOF){for(int i = 1;i<=k+c;i++){for(int j = 1;j<=k+c;j++){scanf("%d", &dis[i][j]);if(dis[i][j] == 0)dis[i][j] = inf;}}for(int t = 1;t<=k+c;t++){for(int i = 1;i<=k+c;i++){for(int j = 1;j<=k+c;j++)dis[i][j] = min(dis[i][j], dis[i][t]+dis[t][j]);}}for(int i = 1;i<=k+c;i++)dis[i][i] = 0;int l = 0, r = 50000;int ans = inf;while(l<=r){int mid = (l+r)/2;DC.init(k+c+2, 0, k+c+1);for(int i = 1;i<=k;i++){for(int j = k+1;j<=k+c;j++){if(dis[i][j]<=mid)DC.add(i, j, 1);}}for(int i = k+1;i<=k+c;i++)DC.add(i, k+c+1, 1);for(int i = 1;i<=k;i++)DC.add(0, i, m);if(DC.maxflow() == c){r = mid-1;ans = min(ans, mid);}elsel = mid+1;}printf("%d\n", ans);}return 0;}


0 0
原创粉丝点击