zoukankan      html  css  js  c++  java
  • 网络流24题 餐巾计划问题 解题报告

    餐巾计划问题

    这建图太厉害了,我想了巨久都没想到怎么控制流量先合法又能流到别的地方去。

    还是思维太烂了qaq

    用了一个把流量拆开的思路,就叫Ta拆流吧

    具体的说,我们对一个点,有一个流量一定要流,但是这个流量也可以给后面的用,我们就把这个流拆开。

    对应此题,先把点拆成(i)(i+n),然后(i)连接(t)表示流量限制,费用为(0),要流满,这也是整个图唯一连接(t)的边。

    然后(i+n)表示当天用完的这个脏餐巾的流,这个流可以给下一天的脏餐巾,可以送去快洗慢洗再给对应的(j)号点代表(j)得到流

    然后建一下买餐巾的流就可以了


    Code:

    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <queue>
    #include <algorithm>
    using std::min;
    #define ll long long
    template <class T>
    void read(T &x)
    {
    	x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    }
    const int N=4010;
    const int M=1e5;
    const int inf=0x3f3f3f3f;;
    int head[N],to[M],Next[M],edge[M],cost[M],cnt=1;
    void add(int u,int v,int w,int c)
    {
    	to[++cnt]=v,edge[cnt]=w,cost[cnt]=c,Next[cnt]=head[u],head[u]=cnt;
    	to[++cnt]=u,edge[cnt]=0,cost[cnt]=-c,Next[cnt]=head[v],head[v]=cnt;
    }
    int n,need[N],s,t;
    int used[N],dis[N],pre[N];
    bool spfa()
    {
    	memset(dis,0x3f,sizeof dis);
    	dis[s]=0;
    	std::queue <int> q;
    	q.push(s);
    	while(!q.empty())
    	{
    		int now=q.front();
    		q.pop();
    		used[now]=0;
    		for(int v,i=head[now];i;i=Next[i])
    			if(edge[i]&&dis[v=to[i]]>dis[now]+cost[i])
    			{
    				dis[v]=dis[now]+cost[i];
    				pre[v]=i;
    				if(!used[v]) q.push(v),used[v]=1;
    			}
    	}
    	return dis[t]<dis[0];
    }
    int main()
    {
    	read(n);
    	for(int i=1;i<=n;i++) read(need[i]);
    	int t1,t2,p0,p1,p2;
    	read(p0),read(t1),read(p1),read(t2),read(p2);
    	s=n<<1|1,t=s+1;
    	for(int i=1;i<=n;i++)
    	{
    		add(s,i,inf,p0);
    		add(i,t,need[i],0);
    		add(s,i+n,need[i],0);
    		if(i<n) add(i+n,i+1+n,inf,0);
    		if(i+t1<=n) add(i+n,i+t1,inf,p1);
    		if(i+t2<=n) add(i+n,i+t2,inf,p2);
    	}
    	ll ans=0;
    	while(spfa())
    	{
    		int mi=inf,now=t;
    		while(pre[now])
    		{
    			mi=min(mi,edge[pre[now]]);
    			now=to[pre[now]^1];
    		}
    		ans+=mi*dis[t];now=t;
    		while(pre[now])
    		{
    			edge[pre[now]]-=mi;
    			edge[pre[now]^1]+=mi;
    			now=to[pre[now]^1];
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    2019.2.26

  • 相关阅读:
    华为云DevCloud为开发者提供高效智能的可信开发环境
    【HC资料合集】2019华为全联接大会主题资料一站式汇总,免费下载!
    在modelarts上部署mask-rcnn模型
    独立物理机和虚拟机比较有什么优势?
    .Net Core下使用MQTT协议直连IoT平台
    解惑Python模块学习,该如何着手操作...
    sar命令,linux中最为全面的性能分析工具之一
    窥探日志的秘密
    Debian 如何使用测试版更新软件包到最新的版本
    如何使用vsphere client 克隆虚拟机
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10438141.html
Copyright © 2011-2022 走看看