ZOJ3496 Assignment
这题也是真恶心……
题目大意是俩公司要运货,每条路有容量上限。然后B公司手里有p个……(技能点?)如果在一条路上放了x个技能点,这条路经过了y个货物,那么B公司就会收x*y的钱。现在要求的是,B公司最大获利和A公司在付费最大时的最小值,和这个问题完全倒过来。
首先有一个结论是B公司一定会把所有技能点一股脑全放在流量最大的那条边上。(贪心显然)注意是当前图上的流量而不是原图容量。那么这个问题就转化成了有上/下界限制的最大最小流。对于第一个问题,我们二分一个流的上界,首先判断这个其实就相当于一个正常的网络流,直接跑dinic即可,然后记录一下是否与一开始跑出来的值是相等的,这样二分求最大值即可。(答案就是当前容量上限的最大值*p)
而对于第二个问题,我们二分流的下界。这个时候就是一个有上下界的网络流,要建立辅助源汇点那一套跑流。不过具体的二分操作依然没变。注意的是,如果在二分过程中,当前的下届大于原来的上界,就直接返回0.最后我们求出最小的下界,然后用它乘以p来更新答案。
但是这题坑点很多的……首先是因为这题重构图很多,注意不能大量用memset。还有就是在head复制的时候不要复制少了,辅助源汇点编号不要小了(因为这题S,T)是给定的……,还有就是这次在判断最小流的时候……删除辅助源汇点最稳妥的做法是把其head设为-1,这样可以保证不会跑到。(不知道为啥,这次如果像以前一样把源汇点直接连的边设为不可走会GG……)
看一下代码吧。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
#define fr friend inline
#define y1 poj
#define mp make_pair
#define pr pair<int,int>
#define fi first
#define sc second
#define pb push_back
#define I puts("Oops")
using namespace std;
typedef long long ll;
const int M = 605;
const int N = 40005;
const ll INF = 1e14;
const double eps = 1e-7;
ll read()
{
ll ans = 0,op = 1;char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
return ans * op;
}
struct edge
{
ll next,to,from,v;
}e[N<<1];
ll Ti,head[M],cur[M],deg[M],x[N],y[N],z[N],n,m,g,ecnt = -1,S,T,S1,T1,tot,p;
ll dep[M],maxn,st,ed;
queue <ll> q;
void add(int x,int y,ll z)
{
e[++ecnt].to = y;
e[ecnt].next = head[x];
e[ecnt].v = z;
head[x] = ecnt;
}
bool bfs(int s,int t)
{
while(!q.empty()) q.pop();
rep(i,0,n+3) cur[i] = head[i];
memset(dep,-1,sizeof(dep));
dep[s] = 0,q.push(s);
while(!q.empty())
{
int k = q.front();q.pop();
for(int i = head[k];~i;i = e[i].next)
{
if(e[i].v && dep[e[i].to] == -1)
dep[e[i].to] = dep[k] + 1,q.push(e[i].to);
}
}
return dep[t] != -1;
}
ll dfs(int s,int t,ll lim)
{
if(s == t || !lim) return lim;
ll flow = 0;
for(int i = cur[s];~i;i = e[i].next)
{
cur[s] = i;
if(dep[e[i].to] != dep[s] + 1) continue;
ll f = dfs(e[i].to,t,min(lim,e[i].v));
if(f)
{
e[i].v -= f,e[i^1].v += f;
flow += f,lim -= f;
if(!lim) break;
}
}
if(!flow) dep[s] = -1;
return flow;
}
ll dinic(int s,int t)
{
ll maxflow = 0;
while(bfs(s,t)) maxflow += dfs(s,t,INF);
return maxflow;
}
bool checkmax(ll k)
{
memset(head,-1,sizeof(head)),ecnt = -1;
rep(i,1,m) add(x[i],y[i],min(k,z[i])),add(y[i],x[i],0);
ll now = dinic(S,T);
return now == g;
}
ll solvemax()
{
ll L = 0,R = maxn,cur = 0;
while(L <= R)
{
ll mid = (L+R) >> 1;
if(checkmax(mid)) cur = mid,R = mid - 1;
else L = mid + 1;
}
return cur * p;
}
bool checkmin(ll k)
{
memset(head,-1,sizeof(head)),memset(deg,0,sizeof(deg));
ecnt = -1,tot = 0;
rep(i,1,m)
{
if(z[i] < k) return 0;
add(x[i],y[i],z[i] - k),add(y[i],x[i],0);
deg[x[i]] += k,deg[y[i]] -= k;
}
S1 = n + 1,T1 = S1 + 1;
rep(i,1,n)
{
if(deg[i] < 0) add(S1,i,-deg[i]),add(i,S1,0);
else add(i,T1,deg[i]),add(T1,i,0),tot += deg[i];
}
add(T,S,INF),add(S,T,0);
ll now = dinic(S1,T1);
if(now != tot) return 0;
head[S1] = head[T1] = -1;
ll cur = dinic(S,T);
return cur == g;
}
ll solvemin()
{
ll L = 0,R = maxn,cur = 0;
while(L <= R)
{
ll mid = (L+R) >> 1;
if(checkmin(mid)) cur = mid,L = mid + 1;
else R = mid - 1;
}
return cur * (ll)p;
}
int main()
{
Ti = read();
while(Ti--)
{
n = read(),m = read(),S = read() + 1,T = read() + 1,p = read();
memset(head,-1,sizeof(head)),maxn = 0,ecnt = -1;
rep(i,1,m)
{
x[i] = read() + 1,y[i] = read() + 1,z[i] = read();
add(x[i],y[i],z[i]),add(y[i],x[i],0),maxn = max(maxn,z[i]);
}
g = dinic(S,T);
printf("%lld ",solvemax());
printf("%lld\n",solvemin());
}
return 0;
}
ZOJ3496 Assignment的更多相关文章
- ZOJ3496:Assignment——题解
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3496 题目大意:A公司从S到T运货,每条路都有一个运货上限,而B公司则有p ...
- Atitit GRASP(General Responsibility Assignment Software Patterns),中文名称为“通用职责分配软件模式”
Atitit GRASP(General Responsibility Assignment Software Patterns),中文名称为"通用职责分配软件模式" 1. GRA ...
- user initialization list vs constructor assignment
[本文连接] http://www.cnblogs.com/hellogiser/p/user_initialization_list.html [分析] 初始化列表和构造函数内的赋值语句有何区别? ...
- Swift 提示:Initialization of variable was never used consider replacing with assignment to _ or removing it
Swift 提示:Initialization of variable was never used consider replacing with assignment to _ or removi ...
- 代写assignment
集英服务社,强于形,慧于心 集英服务社,是一家致力于优质学业设计的服务机构,为大家提供优质原创的学业解决方案.多年来,为海内外学子提供了多份原创优质的学业设计解决方案. 集英服务社,代写essay/a ...
- [Top-Down Approach] Assignment 1: WebServer [Python]
Today I complete Socket Programming Assignment 1 Web Server Here is the code: #!/usr/bin/python2.7 # ...
- default constructor,copy constructor,copy assignment
C++ Code 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...
- Programming Assignment 5: Kd-Trees
用2d-tree数据结构实现在2维矩形区域内的高效的range search 和 nearest neighbor search.2d-tree有许多的应用,在天体分类.计算机动画.神经网络加速.数据 ...
- Programming Assignment 4: 8 Puzzle
The Problem. 求解8数码问题.用最少的移动次数能使8数码还原. Best-first search.使用A*算法来解决,我们定义一个Seach Node,它是当前搜索局面的一种状态,记录了 ...
随机推荐
- hdu 4300 Clairewd’s message(具体解释,扩展KMP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4300 Problem Description Clairewd is a member of FBI. ...
- 如何突破Windows环境限制打开“命令提示符”
如今,许多企业或组织都会通过使用受限的windows环境来减少系统表面的漏洞.系统加固的越好,那么也就意味着能被访问和使用到的功能就越少. 我最近遇到的情况是,一个已经加固的系统同时受到McAfee ...
- 在windows下安装gulp[转]
一.准备工作 1.什么是 npm? npm 是 nodejs 的包管理工具,主要功能就是管理.更新.搜索.发布node的包.Gulp 就是通过 NPM 安装的.关于 NPM 中文介绍,这里有一篇非常不 ...
- sql_视图和函数
创建视图: create view xxx as select * from userinfo; 删除视图: drop view xxx 修改视图: alter view xxx as selete ...
- sql的一些知识
查询 查询表中的所有列(所有信息) SELECT * FROM userinfo 查询某一列(指定) select name from userinfo 查询某一列(指定,去重) SELECT DIS ...
- Solidworks输出Autocad的DWG格式乱码怎么办
Solidworks输出DWG会有很多问题,如果没必要就别这么做,比如你只是想要打印图纸,Solidworks也可以直接打印,而且很方便,不需要转成DWG再打印,如果对方确实需要DWG格式的图纸,你只 ...
- HDU4126Genghis Khan the Conqueror(最小生成树+并查集)
Genghis Khan the Conqueror Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 327680/327680 K ...
- VS中 build,rebuild,clean
一般来说Rebuild=99%*(Clean+Build),效果在非常小的可能性下会不同,一般可以忽略. Rebuild是对Solution下的所有项目,逐个进行 Clean+Build.不论文件更改 ...
- Android Studio 那些事|Activity文件前标识图标显示为 j 而是 c
问题:Activity文件前标识图标显示为 j 而是 c 的图标,或是没有显示,并且自己主动提示不提示 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/fo ...
- 为什么在 Java 中用 (low+high)>>>1 代替 (low+high)/2 或 (low+high)>>1 来计算平均值呢?好在哪里?
>>>与>>是位运算符,只对整型有效(不能用于浮点型).当是整型的时候(low+high)>>1可以代替(low+high)/2.>>>是无 ...