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 ...
随机推荐
- wdcp 使用说明总结(持续更新中。。。)
wdcp 使用说明总结(持续更新中...) 1.移动文件时,如果是上一层,直接填写../即可
- 【南邮】md5 collision write up
源码: <?php $md51 = md5('QNKCDZO'); $a = @$_GET['a']; $md52 = @md5($a); if(isset($a)){ if ($a != 'Q ...
- B - CD UVA - 624
https://cn.vjudge.net/contest/224070#problem/B #include <iostream> #include <cstring> #i ...
- poj2449 Remmarguts' Date K短路 A*
K短路裸题. #include <algorithm> #include <iostream> #include <cstring> #include <cs ...
- Leetcode4--->求两个排序数组的中位数
题目:给定两个排序数组,求两个排序数组的中位数,要求时间复杂度为O(log(m+n)) 举例: Example 1: nums1 = [1, 3] nums2 = [2] The median is ...
- WordPress后台添加侧边栏菜单
add_action('admin_menu', 'register_custom_menu_page'); function register_custom_menu_page() { add_me ...
- VirtualBox 安装XP虚拟机, 安装DB2
个人随笔记录,也许说的不太清楚. 1. 用google搜索VirtualBox, 找到下载地址,下载,我的是win7,下载64bit的. 2. 下载后,安装VBox软件,这个没遇到问题. 3. 因为我 ...
- 九度oj 题目1356:孩子们的游戏(圆圈中最后剩下的数)
题目描述: 每年六一儿童节,JOBDU都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为JOBDU的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈. ...
- JDBC初探(一)
下载好JDBC之后,首先做的应该是查看它的文档 打开connector-j.html import java.sql.Connection; import java.sql.DriverManager ...
- hdu6085[压位+暴力] 2017多校5
/*hdu6085[压位+暴力] 2017多校5*/ /*强行优化..*/ #include <bits/stdc++.h> using namespace std; struct bit ...