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. wdcp 使用说明总结(持续更新中。。。)

    wdcp 使用说明总结(持续更新中...) 1.移动文件时,如果是上一层,直接填写../即可

  2. 【南邮】md5 collision write up

    源码: <?php $md51 = md5('QNKCDZO'); $a = @$_GET['a']; $md52 = @md5($a); if(isset($a)){ if ($a != 'Q ...

  3. B - CD UVA - 624

    https://cn.vjudge.net/contest/224070#problem/B #include <iostream> #include <cstring> #i ...

  4. poj2449 Remmarguts' Date K短路 A*

    K短路裸题. #include <algorithm> #include <iostream> #include <cstring> #include <cs ...

  5. Leetcode4--->求两个排序数组的中位数

    题目:给定两个排序数组,求两个排序数组的中位数,要求时间复杂度为O(log(m+n)) 举例: Example 1: nums1 = [1, 3] nums2 = [2] The median is ...

  6. WordPress后台添加侧边栏菜单

    add_action('admin_menu', 'register_custom_menu_page'); function register_custom_menu_page() { add_me ...

  7. VirtualBox 安装XP虚拟机, 安装DB2

    个人随笔记录,也许说的不太清楚. 1. 用google搜索VirtualBox, 找到下载地址,下载,我的是win7,下载64bit的. 2. 下载后,安装VBox软件,这个没遇到问题. 3. 因为我 ...

  8. 九度oj 题目1356:孩子们的游戏(圆圈中最后剩下的数)

    题目描述: 每年六一儿童节,JOBDU都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为JOBDU的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈. ...

  9. JDBC初探(一)

    下载好JDBC之后,首先做的应该是查看它的文档 打开connector-j.html import java.sql.Connection; import java.sql.DriverManager ...

  10. hdu6085[压位+暴力] 2017多校5

    /*hdu6085[压位+暴力] 2017多校5*/ /*强行优化..*/ #include <bits/stdc++.h> using namespace std; struct bit ...