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 给一些已知(需费用)路径去覆盖一些边 //预先加灌法费用流的更多相关文章

  1. Python实现加密的ZIP文件解压(密码已知)

    博主在上篇博文介绍了<Python实现加密的RAR文件解压(密码已知)>后,又尝试了ZIP文件的解压方法,下面开始分享. 当ZIP文件的压缩密码已知时,可以通过调用zipfile库进行解压 ...

  2. ARCgis已知线裁剪已知面

    经常遇到需要在ArcGIS中,根据已知线图层(要素)切分已知面图层(要素).经过研究,利用topology拓扑菜单中的construct features可以实现.具体如下 现有用线图层A.面图层B, ...

  3. WCF 已知类型和泛型解析程序 KnownType

    数据协定继承 已知类型和泛型解析程序 Juval Lowy 下载代码示例 自首次发布以来,Windows Communication Foundation (WCF) 开发人员便必须处理数据协定继承方 ...

  4. [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

    原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...

  5. 实战分享:如何成功防护1.2T国内已知最大流量DDoS攻击

    作者:腾讯云宙斯盾安全团队&腾讯安全平台部 引言: DDoS攻击势头愈演愈烈,除了攻击手法的多样化发展之外,最直接的还是攻击流量的成倍增长.3月份国内的最大规模DDoS攻击纪录还停留在数百G规 ...

  6. 已知起始点,获取每段等距离途经点的经纬度(用百度js api作)

    已知两个中文地址,自动规划路径,获取路径上每个3公里的点的经纬度 <html> <head> <meta http-equiv="Content-Type&qu ...

  7. 项目文件中的已知 NuGet 属性(使用这些属性,创建 NuGet 包就可以不需要 nuspec 文件啦)

    知道了 csproj 文件中的一些常用 NuGet 属性,创建 NuGet 包时就可以充分发挥新 Sdk 自动生成 NuGet 包的优势,不需要 nuspec 文件啦.(毕竟 nuspec 文件没有 ...

  8. java基础 File与递归练习 使用文件过滤器筛选将指定文件夹下的小于200K的小文件获取并打印按层次打印(包括所有子文件夹的文件) 多层文件夹情况统计文件和文件夹的数量 统计已知类型的数量 未知类型的数量

    package com.swift.kuozhan; import java.io.File; import java.io.FileFilter; /*使用文件过滤器筛选将指定文件夹下的小于200K ...

  9. 已知词频生成词云图(数据库到生成词云)--generate_from_frequencies(WordCloud)

    词云图是根据词出现的频率生成词云,词的字体大小表现了其频率大小. 写在前面: 用wc.generate(text)直接生成词频的方法使用很多,所以不再赘述. 但是对于根据generate_from_f ...

随机推荐

  1. 拓扑排序 topsort

    拓扑排序 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序 ...

  2. jmeter操作mysql数据库

    1.导入jdbc的jar包,因为jmeter本身不能直接连接mysql,所以需要导入第三方的jar包,来连接mysql 2.创建数据库连接配置,mysql的url.端口号.账号.密码 在JDBC Co ...

  3. 前端MVVM模式及其在Vue和React中的体现

    MVVM相关概念 Mvvm 前端数据流框架精讲 1) MVVM典型特点是有四个概念:Model.View.ViewModel.绑定器.MVVM可以是单向绑定也可以是双向绑定甚至是不绑定 2) 绑定器: ...

  4. 实验二 JSP基本动态元素的使用

    实验二  JSP基本动态元素的使用 实验性质:验证性          实验学时:  2学时      实验地点: 一 .实验目的与要求 1.掌握JSP中声明变量.定义方法.java程序片及表达式的使 ...

  5. 【HIHOCODER 1599】逃离迷宫4

    描述 小Hi被坏女巫抓进一座由无限多个格子组成的矩阵迷宫. 小Hi一开始处于迷宫(x, y)的位置,迷宫的出口在(a, b).小Hi发现迷宫被女巫施加了魔法,假设当前他处在(x, y)的位置,那么他只 ...

  6. 计蒜客 The 2018 ACM-ICPC Chinese Collegiate Programming Contest Rolling The Polygon

    include <iostream> #include <cstdio> #include <cstring> #include <string> #i ...

  7. 同一条sql在mysql5.6和5.7版本遇到的问题。

    之前用的是mysql 5.6版本,执行select * from table group by colunm 是可以出结果的, 但是切换的5.7版本,这条sql就报错, Expression #1 o ...

  8. django中的objects.get和objects.filter方法的区别

    为了说明它们两者的区别定义2个models class Student(models.Model): name = models.CharField('姓名', max_length=20, defa ...

  9. 创建dll及使用

    一.创建动态链接库文件 ** 1.打开VS2013,选择文件,新建工程  2.选择新建W32控制台应用程序,这里将工程名改为makeDLL  3.在应用程序类型中选择DLL,点击完成  4.完成以上步 ...

  10. loadrunner参数化数据分配方法

    数据分配方法: 在“Select next row“列表中选择一个数据分配方法,以指示在Vuser脚本执行期间如何从参数文件中取得数据.选项包括”Sequential“.“Random”.“Uniqu ...