zoukankan      html  css  js  c++  java
  • [BZOJ1834][ZJOI2010]network 网络扩容

    BZOJ
    Luogu
    Description
    给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。
    Input
    输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
    Output
    输出文件一行包含两个整数,分别表示问题1和问题2的答案。
    Sample Input

    5 8 2
    1 2 5 8
    2 5 9 9
    5 1 6 2
    5 1 1 8
    1 2 8 7
    2 5 4 9
    1 2 1 1
    1 4 2 1
    

    Sample Output

    13 19
    

    30%的数据中,N<=100
    100%的数据中,N<=1000,M<=5000,K<=10

    题解

    第一问裸的Dinic
    第二问再加入容量为K费用为W的边,可以在原图上面跑,因为是不影响的。

    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N = 5005;
    const int inf = 1e9;
    struct edge{int to,next,w,cost;}a[N<<2];
    int n,m,k,s,t,U[N],V[N],C[N],W[N],head[N],cnt=1,dep[N],cur[N],dis[N],vis[N],pe[N],ans;
    queue<int>Q;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    void link(int u,int v,int w,int cost)
    {
    	a[++cnt]=(edge){v,head[u],w,cost};
    	head[u]=cnt;
    	a[++cnt]=(edge){u,head[v],0,-cost};
    	head[v]=cnt;
    }
    bool bfs()
    {
    	memset(dep,0,sizeof(dep));
    	dep[1]=1;Q.push(1);
    	while (!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for (int e=head[u];e;e=a[e].next)
    			if (a[e].w&&!dep[a[e].to])
    				dep[a[e].to]=dep[u]+1,Q.push(a[e].to);
    	}
    	return dep[n];
    }
    int dfs(int u,int flow)
    {
    	if (u==n)
    		return flow;
    	for (int &e=cur[u];e;e=a[e].next)
    		if (a[e].w&&dep[a[e].to]==dep[u]+1)
    		{
    			int temp=dfs(a[e].to,min(flow,a[e].w));
    			if (temp) {a[e].w-=temp;a[e^1].w+=temp;return temp;}
    		}
    	return 0;
    }
    int Dinic()
    {
    	int res=0;
    	while (bfs())
    	{
    		for (int i=1;i<=n;i++) cur[i]=head[i];
    		while (int temp=dfs(1,inf)) res+=temp;
    	}
    	return res;
    }
    bool spfa()
    {
    	memset(dis,63,sizeof(dis));
    	dis[n+1]=0;Q.push(n+1);
    	while (!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for (int e=head[u];e;e=a[e].next)
    		{
    			int v=a[e].to;
    			if (a[e].w&&dis[v]>dis[u]+a[e].cost)
    			{
    				dis[v]=dis[u]+a[e].cost;pe[v]=e;
    				if (!vis[v]) vis[v]=1,Q.push(v);
    			}
    		}
    		vis[u]=0;
    	}
    	if (dis[n]==dis[0]) return false;
    	int sum=inf;
    	for (int i=n;i!=n+1;i=a[pe[i]^1].to)
    		sum=min(sum,a[pe[i]].w);
    	for (int i=n;i!=n+1;i=a[pe[i]^1].to)
    		a[pe[i]].w-=sum,a[pe[i]^1].w+=sum;
    	ans+=dis[n]*sum;
    	return true;
    }
    int main()
    {
    	n=gi();m=gi();k=gi();
    	for (int i=1;i<=m;i++)
    	{
    		U[i]=gi();V[i]=gi();
    		C[i]=gi();W[i]=gi();
    		link(U[i],V[i],C[i],0);
    	}
    	link(n+1,1,k,0);
    	printf("%d ",Dinic());
    	for (int i=1;i<=m;i++)
    		link(U[i],V[i],k,W[i]);
    	while (spfa());
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    [Unity] 2D开发学习教程
    [Unity] 查找资源
    [Unity] UGUI研究院之游戏摇杆
    [Unity] Unity3D研究院编辑器之自定义默认资源的Inspector面板
    [Unity] Unity3D研究院编辑器之独立Inspector属性
    [Unity] 精灵动画制作中需要注意的一些问题
    [Unity] 常用技巧收集
    IDEA相关设置
    Hive配置文件hive-site.xml
    MySql通用二进制版本在Linux(Ubuntu)下安装与开启服务
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8159192.html
Copyright © 2011-2022 走看看