zoukankan      html  css  js  c++  java
  • 【bzoj4108】[Wf2015]Catering 有上下界费用流

    原文地址:http://www.cnblogs.com/GXZlegend/p/6832537.html


    题目描述

    有一家装备出租公司收到了按照时间顺序排列的n个请求.

    这家公司有k个搬运工.每个搬运工可以搬着一套装备按时间顺序去满足一些请求.一个搬运工从第i个请求的位置把东西搬到第j个请求的位置需要一些费用.公司的编号是1,请求的编号是2到n+1.所有搬运工必需从公司出发.
    求满足所有请求所需的最小搬运费用.

    输入

    有可能有多组数据.(实际上没有)

    第一行两个正整数n,k.
    接下来n行,第i行有n-i+1个数.第j个数表示把装备从i搬到i+j的花费.

    输出

    输出一行一个整数表示最小花费.

    样例输入

    1 1
    10

    样例输出

    10


    题目大意

    给定一个竞赛图,边有边权且方向总是由编号小指向编号大。给你k次机会从1沿边走向其它点,要求除1以外的每个点都需要且只能经过一次,问最小的边权之和。

    题解

    有上下界费用流,难在翻译题目

    将每个点拆成两个,之间连边,上下界均为1。

    用一个单独的点连向1限制流量,再加入两点之间的边。

    然后求有上下界费用流。

    另:并没有多组测试数据

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define inf 0x3f3f3f3f
    using namespace std;
    queue<int> q;
    int head[300] , to[100000] , val[100000] , cost[100000] , next[100000] , cnt = 1 , s , t , dis[300] , from[300] , pre[300];
    void add(int x , int y , int v , int c)
    {
    	to[++cnt] = y , val[cnt] = v , cost[cnt] = c , next[cnt] = head[x] , head[x] = cnt;
    	to[++cnt] = x , val[cnt] = 0 , cost[cnt] = -c , next[cnt] = head[y] , head[y] = cnt;
    }
    bool spfa()
    {
    	int x , i;
    	memset(dis , 0x3f , sizeof(dis));
    	memset(from , -1 , sizeof(from));
    	dis[s] = 0 , q.push(s);
    	while(!q.empty())
    	{
    		x = q.front() , q.pop();
    		for(i = head[x] ; i ; i = next[i])
    			if(val[i] && dis[to[i]] > dis[x] + cost[i])
    				dis[to[i]] = dis[x] + cost[i] , from[to[i]] = x , pre[to[i]] = i , q.push(to[i]);
    	}
    	return ~from[t];
    }
    int mincost()
    {
    	int ans = 0 , i , k;
    	while(spfa())
    	{
    		k = inf;
    		for(i = t ; i != s ; i = from[i]) k = min(k , val[pre[i]]);
    		ans += k * dis[t];
    		for(i = t ; i != s ; i = from[i]) val[pre[i]] -= k , val[pre[i] ^ 1] += k;
    	}
    	return ans;
    }
    int main()
    {
    	int n , k , i , j , x;
    	scanf("%d%d" , &n , &k);
    	s = 2 * n + 2 , t = 2 * n + 3 , add(0 , 1 , k , 0);
    	for(i = 2 ; i <= n + 1 ; i ++ ) scanf("%d" , &x) , add(1 , i , inf , x) , add(s , i + n , 1 , 0) , add(i , t , 1 , 0) , add(i + n , 0 , inf , 0);
    	for(i = 2 ; i <= n ; i ++ )
    		for(j = i + 1 ; j <= n + 1 ; j ++ )
    			scanf("%d" , &x) , add(i + n , j , inf , x);
    	printf("%d
    " , mincost());
    	return 0;
    }

     

  • 相关阅读:
    JavaScript 检测对象类型
    memorize
    高阶函数
    JavaScript 中的不完全函数
    VS C# Winform 重写进度条
    使用ECLIPSE+RED搭建RF自动化测试框架
    NOIP2018濒死记
    HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)
    打FFT时中发现的卡常技巧
    Dynamic Rankings || 动态/静态区间第k小(主席树)
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6832537.html
Copyright © 2011-2022 走看看