zoukankan      html  css  js  c++  java
  • 【bzoj2245】 SDOI2011—工作安排

    http://www.lydsy.com/JudgeOnline/problem.php?id=2245 (题目链接)

    题意

      n个产品,每个需要造C[i]件;m个员工,每个员工可以制造一些产品;每个员工的愤怒值是关于制造产品数的递增分段函数。所有员工的愤怒值之和最少是多少。

    Solution

      按照题意连边构图,跑费用即可。

    细节

      开LL。

    代码

    // bzoj2245
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define LL long long
    #define inf 2147483640
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=100010;
    struct edge {int from,to,next,w,c;}e[maxn*10];
    int p[maxn],f[maxn],d[maxn],head[maxn],vis[maxn],s[maxn],T[300][300],w[300][300];
    int n,m,cnt=1,es,et;
    
    void link(int u,int v,int w,int c) {
    	e[++cnt]=(edge){u,v,head[u],w,c};head[u]=cnt;
    	e[++cnt]=(edge){v,u,head[v],0,-c};head[v]=cnt;
    }
    LL SPFA() {
    	queue<int> q;
    	memset(f,0,sizeof(f));
    	memset(d,0x7f,sizeof(d));
    	q.push(es);d[es]=0;f[es]=inf;
    	while (!q.empty()) {
    		int x=q.front();q.pop();vis[x]=0;
    		for (int i=head[x];i;i=e[i].next) if (e[i].w && d[e[i].to]>d[x]+e[i].c) {
    				d[e[i].to]=d[x]+e[i].c;
    				f[e[i].to]=min(f[x],e[i].w);
    				p[e[i].to]=i;
    				if (!vis[e[i].to]) q.push(e[i].to),vis[e[i].to]=1;
    			}
    	}
    	if (f[et]==0) return 0;
    	for (int i=p[et];i;i=p[e[i].from]) e[i].w-=f[et],e[i^1].w+=f[et];
    	return (LL)f[et]*d[et];
    }
    LL EK() {
    	LL ans=0;
    	while (1) {
    		LL x=SPFA();
    		if (x==0) return ans;
    		ans+=x;
    	}
    }
    int main() {
    	scanf("%d%d",&m,&n);
    	es=10000;et=es+1;
    	for (int x,i=1;i<=n;i++) {
    		scanf("%d",&x);
    		link(i+m,et,x,0);
    	}
    	for (int i=1;i<=m;i++) link(es,i,inf,0);
    	for (int i=1;i<=m;i++)
    		for (int x,j=1;j<=n;j++) {
    			scanf("%d",&x);
    			if (x) link(n+m+i,j+m,inf,0);
    		}
    	for (int i=1;i<=m;i++) {
    		scanf("%d",&s[i]);
    		for (int j=1;j<=s[i];j++) scanf("%d",&T[i][j]);
    		for (int j=1;j<=s[i]+1;j++) scanf("%d",&w[i][j]);
    		for (int j=1;j<=s[i];j++) link(i,n+m+i,T[i][j]-T[i][j-1],w[i][j]);
    		link(i,n+m+i,inf,w[i][s[i]+1]);
    	}
    	printf("%lld",EK());
    	return 0;
    }
    

      

  • 相关阅读:
    其他标签
    数组和全局变量
    字符串处理
    运算符
    PHP安装配置工具
    String、StringBuffer与StringBuilder之间区别
    mybits——1
    异常
    ubuntu 系统错误:Error : BrokenCount > 0解决
    ubuntu配置VScode
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6201698.html
Copyright © 2011-2022 走看看