zoukankan      html  css  js  c++  java
  • hdu 4494 Teamwork 最小费用最大流

    Teamwork

    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

    http://acm.hdu.edu.cn/showproblem.php?pid=4494

    Description

    Some locations in city A has been destroyed in the fierce battle. So the government decides to send some workers to repair these locations. There are m kinds of workers that were trained for different skills. Each location need some number of some kinds of workers and has a schedule that at what time can the repair begins, and the time cost of repair. Any job cannot begin until all the workers required arrived. 
    For example, location 1 needs 2 workers of type 1 and 3 workers of type 2, and the beginning time and time cost is 100 minute and 90 minute correspondingly, then 5 workers that satisfy the requirement should arrive before 100 minute, start working at 100 minute and get the job done at 190 minute. Notice that two different types of workers cannot replace each other, so with 3 workers of type 1 and only 2 workers of type 2, this job cannot be done. 
    Workers can go from one location to another after their jobs are done. You can take the Euclidean distance between locations as the time workers need to travel between them. Each worker should be sent from a depot initially at 0 minute. Now your task is to determine the minimum number of workers needed to be sent from depot so that all the jobs can be done.

    Input

    There are multiple test cases, the integer on the first line T (T<25) indicates the number of test cases. 
    Each test case begins with two integers n (<=150), the number of location(including the depot) and m(<=5), the number of different skills. 
    The next line gives two integers x 0, y 0 indicates the coordinate of depot. 
    Then follows n - 1 lines begins with 4 integer numbers: x i, y i, b i(b i>0), p i(p i>0), (x i, y i) gives the coordinate of the i-th location, bi gives the beginning time and pi gives the time cost. The rest of the line gives m non-negative integers v 1, v 2, ..., v m, of which the i-th number indicates the the number of workers of type i needed (for all v i, 0<=v i<10, each location at least requires one worker). 
    All integers are less than 1000000 (10 6).

    Output

    For each test cases output one line, the minimum workers to be sent. It is guaranteed that there's always a feasible solution that all the jobs can be done.

    Sample Input

    2 4 1 0 0 0 1 1 1 3 1 1 3 3 4 1 0 10 1 5 4 1 0 0 0 1 1 1 3 1 1 3 3 4 1 0 3 1 5

    Sample Output

    5 9

    HINT

    题意

    有n个工地,工地的位置在xi,yi,工地必须在bi时间开工,要求持续修建ei时间

    每个工地需要m种人,每种人需要vk个

    工地做完了的,可以派去其他工地

    问你最少需要多少个工人

    题解:

    最小费用最大流

    拆点,建边,u,v,容量,费用

    addedge(0,2*i-1,p[i].v[TTT],0);
    addedge(2*i-1,3*n,p[i].v[TTT],1);
    addedge(2*i,3*n,p[i].v[TTT],0);

    向能够到达的其他点

    addedge(2*i-1,2*j,p[i].v[TTT],0);

    虽然这道题是DAG,但是跑背包会TLE。。。

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <bitset>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200500
    #define mod 1001
    #define eps 1e-9
    #define pi 3.1415926
    int Num;
    //const int inf=0x7fffffff;
    const ll inf=999999999;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //*************************************************************************************
    struct Node
    {
        int x,y,b,e;
        int v[6];
        int V[6];
    };
    Node p[200];
    const int MAXN = 10000;
    const int MAXM = 100000;
    const int INF = 0x3f3f3f3f;
    struct Edge
    {
        int to, next, cap, flow, cost;
        int x, y;
    } edge[MAXM],HH[MAXN],MM[MAXN];
    int head[MAXN],tol;
    int pre[MAXN],dis[MAXN];
    bool vis[MAXN];
    int N, M;
    char map[MAXN][MAXN];
    void init()
    {
        N = MAXN;
        tol = 0;
        memset(head, -1, sizeof(head));
    }
    void addedge(int u, int v, int cap, int cost)//左端点,右端点,容量,花费
    {
        edge[tol]. to = v;
        edge[tol]. cap = cap;
        edge[tol]. cost = cost;
        edge[tol]. flow = 0;
        edge[tol]. next = head[u];
        head[u] = tol++;
        edge[tol]. to = u;
        edge[tol]. cap = 0;
        edge[tol]. cost = -cost;
        edge[tol]. flow = 0;
        edge[tol]. next = head[v];
        head[v] = tol++;
    }
    bool spfa(int s, int t)
    {
        queue<int>q;
        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;
    }
    //返回的是最大流, cost存的是最小费用
    int minCostMaxflow(int s, int t, int &cost)
    {
        int flow = 0;
        cost = 0;
        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;
        }
        return flow;
    }
    double DDis(Node A,Node B)
    {
        return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
    }
    int main()
    {
        int t;scanf("%d",&t);
        while(t--)
        {
            int n=read(),m=read();
            int x;
            for(int i=0;i<2;i++)
                scanf("%d",&x);
            n--;
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d%d%d",&p[i].x,&p[i].y,&p[i].b,&p[i].e);
                p[i].e+=p[i].b;
                for(int j=1;j<=m;j++)
                {
                    scanf("%d",&p[i].v[j]);
                }
            }
            int Ans = 0;
            for(int TTT=1;TTT<=m;TTT++)
            {
                init();
                for(int i=1;i<=n;i++)
                {
                    addedge(0,2*i-1,p[i].v[TTT],0);
                    addedge(2*i-1,3*n,p[i].v[TTT],1);
                    addedge(2*i,3*n,p[i].v[TTT],0);
                }
                for(int i=1;i<=n;i++)
                {
                    for(int j=1;j<=n;j++)
                    {
                        if(i==j)continue;
                        if(1.0*p[i].e+1.0*DDis(p[i],p[j])<=1.0*p[j].b)
                        {
                            addedge(2*i-1,2*j,p[i].v[TTT],0);
                        }
                    }
                }
                int s=0,t=3*n;
                int ans1 = 0,ans2 = 0;
                ans1 = minCostMaxflow(s,t,ans2);
                Ans+=ans2;
            }
            printf("%d
    ",Ans);
        }
    }
  • 相关阅读:
    [笔记].新唐M051型号的后缀解读
    [转载].怎样理解阻抗匹配
    [原创][连载].基于SOPC的简易数码相框 Nios II SBTE部分(软件部分) TFTLCD(控制器为ILI9325)驱动
    [转载].关于STM32的CPU为32位,定时器却为16位的探讨
    [笔记][朝花夕拾][Multisim基础电路范例].第一章 RLC电路,第九节 基尔霍夫电流定律
    [原创].如何解决Nios II SBTE中出现的undefined reference to `xxx'警告
    [原创][连载].基于SOPC的简易数码相框 Nios II SBTE部分(软件部分) ADS7843触摸屏驱动测试
    [笔记][朝花夕拾][Multisim基础电路范例].第一章 RLC电路,第十一节 叠加定理
    [笔记].怎样在IAR中加入编译所需库的头文件?
    [原创][连载].基于SOPC的简易数码相框 Nios II SBTE部分(软件部分) 从SD卡内读取图片文件,然后显示在TFTLCD上
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4998944.html
Copyright © 2011-2022 走看看