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. Inkscape基础

    What is Inkscape A program for creating vector graphics For Windows, Mac OS, and Linux Open source F ...

  2. Java-JFrame开发汇总整理

    Java-JFrame开发汇总整理 在CS框架下,可以通过java代码开发JFrame弹窗体的功能,即类似于QQ登录等安装在计算机中的程序,通过java开发CS中C即客户端的一般用到的知识点如下: 一 ...

  3. crond定时操作 crontab

    * * * * *  分别表示 分钟  小时  日  月  星期(0-6) 30 17,28,19 * * *  或 30 17-19 * * *  在每天的17-19小时半点时刻执行 30 8-18 ...

  4. 【linux】文件默认权限:umask

    在默认权限的属性上,目录与文件是不一样的.从第六章我们知道 x 权限对於目录是非常重要的! 但是一般文件的创建则不应该有运行的权限,因为一般文件通常是用在於数据的记录嘛!当然不需要运行的权限了. 因此 ...

  5. 创建 Django 步骤

    1.创建项目 django-admin startproject 项目名称 2.创建APP python manage.py startapp app名称 3.修改settings.py文件 3.1设 ...

  6. Python 建模步骤

    #%% #载入数据 .查看相关信息 import pandas as pd import numpy as np from sklearn.preprocessing import LabelEnco ...

  7. python爬虫基础16-cookie在爬虫中的应用

    Cookie的Python爬虫应用 Cookie是什么 Cookie,有时也用其复数形式 Cookies,英文是饼干的意思.指某些网站为了辨别用户身份.进行 session 跟踪而储存在用户本地终端上 ...

  8. leetcode-11-dfs

    DFS算法: explore(G, v) visited(v) = trueprevisit(v) for each edge(v, u) in E: if not visited(u): explo ...

  9. QT添加自定义信号后编译出现undefined reference

    QT添加自定义信号后编译出现undefined reference 这是需要重新生成qmake: build --->run qmake

  10. nrf528xx bootloader 模块介绍(转载)

    转载https://www.cnblogs.com/rfnets/p/8205521.html 1. bootloader 的基本功能: 启动应用 几个应用之间切换 初始化外设 nordic nrf5 ...