hdu3947 给一些已知(需费用)路径去覆盖一些边 //预先加灌法费用流
River Problem
题意:一个有向树(河流),只有一个汇点1,每条边只有一个出度。有些河道有污染指数xi,必需要治理,有m段路径,可以去覆盖这些,每被覆盖一次,xi降低响应值。
:即 给出一些边必需要覆盖的次数,用m段路径去覆盖,每次覆盖有相应费用,求最小费用。
思路:这题被誉为难题,给一个网络流,给出一些边的流量下界,以及给用某些路段流量去流满足要求。这里与正常网络流相悖,是wi>=xi,所以用:
预先加灌法:(预先灌入大流量(相应干道大小灌溉相应流量),要覆盖的减掉,使达不到预期流量,而用添加费用来补充,恰好跑最小费用最大流)
相应河道流量为U-wi(wi为要覆盖次数),再给的路径直接连边。如果没有wi,那么必然最大流为 U*主干道流量。应该有这些污染指数,所以在某些边流量变窄了!,再没有花费路径补充流量的情况下,比如达不到最大流,就无解,这样起到补充作用。
取之官方思路:
这里u取wi最大值略大(50)即可.
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxv=301,maxe=10001;
int nume=0;int head[maxv];int e[maxe][4];
void inline adde(int i,int j,int c,int w) //网络流图
{
e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
e[nume][2]=c;e[nume++][3]=w;
e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
e[nume][2]=0;e[nume++][3]=-w;
}
int nume2=0;int head2[maxv];int e2[maxe][4];
void inline adde2(int i,int j,int c,int w) //原图
{
e2[nume2][0]=j;e2[nume2][1]=head2[i];head2[i]=nume2;
e2[nume2][2]=c;e2[nume2++][3]=w;
}
int numfa[maxv]; //即dp[i]:i的边干道宽度/包含叶子数
int outd[maxv];
int n,m;int ss,tt;
int inq[maxv];int d[maxv]; int pre[maxv];int prv[maxv];
bool spfa(int &sum,int &sumflow)
{
for(int i=0;i<=n;i++)
{
inq[i]=0;
d[i]=inf;
}
queue<int>q;
q.push(ss);
inq[ss]=1;
d[ss]=0;
while(!q.empty())
{
int cur=q.front();
q.pop();
inq[cur]=0;
for(int i=head[cur];i!=-1;i=e[i][1])
{
int v=e[i][0];
if(e[i][2]>0&&d[cur]+e[i][3]<d[v])
{
d[v]=d[cur]+e[i][3];
pre[v]=i;
prv[v]=cur;
if(!inq[v])
{
q.push(v);
inq[v]=1;
}
}
}
}
if(d[tt]==inf)return 0;
int cur=tt;int minf=inf;
while(cur!=ss)
{
int fe=pre[cur];
minf=e[fe][2]<minf?e[fe][2]:minf;
cur=prv[cur];
}
cur=tt;
while(cur!=ss)
{
e[pre[cur]][2]-=minf;
e[pre[cur]^1][2]+=minf;
cur=prv[cur];
}
sum+=d[tt]*minf;
sumflow+=minf;
return 1;
}
int sumcost(int &sumflow)
{
int sum=0;
while(spfa(sum,sumflow));
return sum;
}
int dfs_getnumfa(int u) // 记录出i所包含的叶子数(源点数)
{
if(u==0)return 1;
for(int i=head2[u];i!=-1;i=e2[i][1])
{
int v=e2[i][0];
numfa[u]+=dfs_getnumfa(v);
}
return numfa[u];
}
void read_build()
{
scanf("%d",&n);
int aa,bb,cc,ww;
for(int i=0;i<n-1;i++)
{
scanf("%d%d%d",&aa,&bb,&cc);
adde2(bb,aa,0,cc); //反向建树,原来的是倒的树
outd[bb]++;
}
for(int i=1;i<=n;i++)
{
if(outd[i]==0) //源点
{
adde2(i,0,0,0);
}
}
numfa[0]=1;
dfs_getnumfa(1);
for(int i=0;i<=n;i++)
{
for(int j=head2[i];j!=-1;j=e2[j][1])
{
int v=e2[j][0];
adde(v,i,numfa[v]*50-e2[j][3],0);
}
}
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d%d%d%d",&aa,&bb,&cc,&ww);
adde(aa,bb,cc,ww);
}
}
void init()
{
nume=0;
memset(head,-1,sizeof(head));
nume2=0;
memset(head2,-1,sizeof(head2));
memset(numfa,0,sizeof(numfa));
memset(outd,0,sizeof(outd));
ss=0;tt=1;
}
int main()
{
int T;
scanf("%d",&T);
for(int ii=1;ii<=T;ii++)
{
init();
read_build();
int sumflow=0;
int ans=sumcost(sumflow);
if(sumflow!=numfa[1]*50)
printf("Case #%d: -1\n",ii);
else
printf("Case #%d: %d\n",ii,ans);
}
return 0;
}
hdu3947 给一些已知(需费用)路径去覆盖一些边 //预先加灌法费用流的更多相关文章
- Python实现加密的ZIP文件解压(密码已知)
博主在上篇博文介绍了<Python实现加密的RAR文件解压(密码已知)>后,又尝试了ZIP文件的解压方法,下面开始分享. 当ZIP文件的压缩密码已知时,可以通过调用zipfile库进行解压 ...
- ARCgis已知线裁剪已知面
经常遇到需要在ArcGIS中,根据已知线图层(要素)切分已知面图层(要素).经过研究,利用topology拓扑菜单中的construct features可以实现.具体如下 现有用线图层A.面图层B, ...
- WCF 已知类型和泛型解析程序 KnownType
数据协定继承 已知类型和泛型解析程序 Juval Lowy 下载代码示例 自首次发布以来,Windows Communication Foundation (WCF) 开发人员便必须处理数据协定继承方 ...
- [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)
原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...
- 实战分享:如何成功防护1.2T国内已知最大流量DDoS攻击
作者:腾讯云宙斯盾安全团队&腾讯安全平台部 引言: DDoS攻击势头愈演愈烈,除了攻击手法的多样化发展之外,最直接的还是攻击流量的成倍增长.3月份国内的最大规模DDoS攻击纪录还停留在数百G规 ...
- 已知起始点,获取每段等距离途经点的经纬度(用百度js api作)
已知两个中文地址,自动规划路径,获取路径上每个3公里的点的经纬度 <html> <head> <meta http-equiv="Content-Type&qu ...
- 项目文件中的已知 NuGet 属性(使用这些属性,创建 NuGet 包就可以不需要 nuspec 文件啦)
知道了 csproj 文件中的一些常用 NuGet 属性,创建 NuGet 包时就可以充分发挥新 Sdk 自动生成 NuGet 包的优势,不需要 nuspec 文件啦.(毕竟 nuspec 文件没有 ...
- java基础 File与递归练习 使用文件过滤器筛选将指定文件夹下的小于200K的小文件获取并打印按层次打印(包括所有子文件夹的文件) 多层文件夹情况统计文件和文件夹的数量 统计已知类型的数量 未知类型的数量
package com.swift.kuozhan; import java.io.File; import java.io.FileFilter; /*使用文件过滤器筛选将指定文件夹下的小于200K ...
- 已知词频生成词云图(数据库到生成词云)--generate_from_frequencies(WordCloud)
词云图是根据词出现的频率生成词云,词的字体大小表现了其频率大小. 写在前面: 用wc.generate(text)直接生成词频的方法使用很多,所以不再赘述. 但是对于根据generate_from_f ...
随机推荐
- 拓扑排序 topsort
拓扑排序 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序 ...
- jmeter操作mysql数据库
1.导入jdbc的jar包,因为jmeter本身不能直接连接mysql,所以需要导入第三方的jar包,来连接mysql 2.创建数据库连接配置,mysql的url.端口号.账号.密码 在JDBC Co ...
- 前端MVVM模式及其在Vue和React中的体现
MVVM相关概念 Mvvm 前端数据流框架精讲 1) MVVM典型特点是有四个概念:Model.View.ViewModel.绑定器.MVVM可以是单向绑定也可以是双向绑定甚至是不绑定 2) 绑定器: ...
- 实验二 JSP基本动态元素的使用
实验二 JSP基本动态元素的使用 实验性质:验证性 实验学时: 2学时 实验地点: 一 .实验目的与要求 1.掌握JSP中声明变量.定义方法.java程序片及表达式的使 ...
- 【HIHOCODER 1599】逃离迷宫4
描述 小Hi被坏女巫抓进一座由无限多个格子组成的矩阵迷宫. 小Hi一开始处于迷宫(x, y)的位置,迷宫的出口在(a, b).小Hi发现迷宫被女巫施加了魔法,假设当前他处在(x, y)的位置,那么他只 ...
- 计蒜客 The 2018 ACM-ICPC Chinese Collegiate Programming Contest Rolling The Polygon
include <iostream> #include <cstdio> #include <cstring> #include <string> #i ...
- 同一条sql在mysql5.6和5.7版本遇到的问题。
之前用的是mysql 5.6版本,执行select * from table group by colunm 是可以出结果的, 但是切换的5.7版本,这条sql就报错, Expression #1 o ...
- django中的objects.get和objects.filter方法的区别
为了说明它们两者的区别定义2个models class Student(models.Model): name = models.CharField('姓名', max_length=20, defa ...
- 创建dll及使用
一.创建动态链接库文件 ** 1.打开VS2013,选择文件,新建工程 2.选择新建W32控制台应用程序,这里将工程名改为makeDLL 3.在应用程序类型中选择DLL,点击完成 4.完成以上步 ...
- loadrunner参数化数据分配方法
数据分配方法: 在“Select next row“列表中选择一个数据分配方法,以指示在Vuser脚本执行期间如何从参数文件中取得数据.选项包括”Sequential“.“Random”.“Uniqu ...