hdu 4494 最小费用流
思路:这题我在下午重现的时候就用的费用流做,可是各种悲催的超时,只是我一开始的那种建图方式多了一个二分查找。
戏剧性的是,求距离的返回值写成int型了,CodeBlock编译器又没有警告,然后就WA啊WA,AC率一下就被拉低了。
当然,对每种工人分别建图是不变的,因为每种工人互不影响。
后来想到了一个较好的建图方式,将每个点拆成3个点,i,i+n,i+2*n。
1号点就是仓库,也就是超级源点,3*n+1号点为超级汇点。
由1号点想每个i建一条流量为ty[i][j],费用为1的边。表示每次增加流量,人数就增加。
由i向i+2*n建一条流量为ty[i][j],费用为0的边。
由i+2*n向汇点建一条流量为ty[i][j],费用为0的边。
由1向每个i+n建一条流量为ty[i][j],费用为0的边。
对i号点,寻找开始时间sta[k]满足b[i]+p[i]+d[i][j]的点k,然后由i+n向k+2*n建一条流量为ty[i][j],费用为0的边。
这样,如果i号点的工人能到k号点工作,那么k号点的k+2*n到3*n+1的流量就会减少ty[i][j]。
#include<iostream>
#include<cstring>
#include<cstring>
#include<cmath>
#include<cstdio>
#define inf 100000000
using namespace std;
const int Maxn = ;
struct Edge{
int v;
int val;
int cost;
int next;
}edge[Maxn*];
struct Point{
double x,y;
}p[Maxn];
int head[Maxn],n,m,k;
int e;
int dis[Maxn],pre[Maxn], pos[Maxn],sta[Maxn],en[Maxn],ty[Maxn][],flow;
int que[Maxn*];
double d[Maxn][Maxn];
bool vis[Maxn];
void add(int u, int v, int val, int cost)
{
edge[e].v = v;
edge[e].val = val;
edge[e].cost = cost;
edge[e].next = head[u];
head[u] = e++;
edge[e].v = u;
edge[e].val = ;
edge[e].cost = -cost;
edge[e].next = head[v];
head[v] = e++;
}
double DIS(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void init()
{
memset(head,-,sizeof(head));
e=;
}
bool spfa(int s, int t)
{
int i;
memset(pre, -, sizeof(pre));
memset(vis, , sizeof(vis));
int Head, tail;
Head = tail = ;
for(i = ; i < Maxn; i++)
dis[i] = inf;
que[tail++] = s;
pre[s] = s;
dis[s] = ;
vis[s] = ;
while(Head != tail)
{
int now = que[Head++];
vis[now] = ;
for(i=head[now]; i != -; i = edge[i].next)
{
int adj = edge[i].v;
if(edge[i].val > && dis[now] + edge[i].cost < dis[adj])
{
dis[adj] = dis[now] + edge[i].cost;
pre[adj] = now;
pos[adj] = i;
if(!vis[adj])
{
vis[adj] = ;
que[tail++] = adj;
}
}
}
}
return pre[t] != -;
}
int MinCostFlow(int s, int t)
{
int i;
int cost = ;
flow = ;
while(spfa(s, t))
{
int f = ;
for(i = t; i != s; i = pre[i])
if (edge[pos[i]].val < f)
f = edge[pos[i]].val;
flow += f;
cost += dis[t] * f;
for(i = t; i != s; i = pre[i])
{
edge[pos[i]].val -= f;
edge[pos[i] ^ ].val += f;
}
}
return cost;
}
void build(int type)
{
int i,j;
init();
for(i=;i<=n;i++){
add(,i,ty[i][type],);
add(i,i+*n,ty[i][type],);
add(,i+n,ty[i][type],);
add(i+*n,*n+,ty[i][type],);
for(j=;j<=n;j++){
if(sta[i]+en[i]+d[i][j]<=sta[j]){
add(i+n,j+*n,ty[i][type],);
}
}
}
}
int solve()
{
int i,j,u,v;
int ans=;
for(i=;i<=m;i++){
build(i);
ans+=MinCostFlow(,*n+);
}
return ans;
}
int main()
{
int i,j,u,v,c,t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&n,&m);
scanf("%lf%lf",&p[].x,&p[].y);
for(i=;i<=n;i++){
scanf("%lf%lf%d%d",&p[i].x,&p[i].y,&sta[i],&en[i]);
for(j=;j<=m;j++){
scanf("%d",&ty[i][j]);
}
}
for(i=;i<=n;i++){
for(j=i+;j<=n;j++){
d[i][j]=d[j][i]=DIS(p[i],p[j]);
}
}
printf("%d\n",solve());
}
return ;
}
hdu 4494 最小费用流的更多相关文章
- hdu 4494 Teamwork 最小费用最大流
Teamwork Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4494 ...
- Going Home (hdu 1533 最小费用流)
集训的图论都快结束了,我才看懂了最小费用流,惭愧啊. = = 但是今天机械键盘到了,有弄好了自行车,好高兴\(^o^)/~ 其实也不是看懂,就会套个模板而已.... 这题最重要的就是一个: 多组输入一 ...
- hdu 1853 最小费用流好题 环的问题
Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others) Tota ...
- HDU 6188最小费用流
题目链接:http://hdu.hustoj.com/showproblem.php?pid=6118 掉坑里了,图很好建,Wa了一发,看了Disscuss里面有人提供了一组样例,画图发现:最小流模板 ...
- hdu 4744 最小费用流
#include <cstdio> #include <queue> #include <cstring> #include <cmath> #defi ...
- hdu 4411 最小费用流
思路:主要就是要把一个每个城市拆为两个点,建一条容量为1,费用为-inf的边,保证每个城市都会被遍历. /*最小费用最大流*/ #include<iostream> #include< ...
- hdu 4494 Teamwork (可行流的最小流)
去年通话邀请赛的B题,当时居然过的那么少...明明是一道非常裸的可行流最小流麽..仅仅要对每种人分别求一下可行最小流加起来就能够了.建图是对每一个点拆点,容量上下届都设为v[i],然后每一个点间能连边 ...
- HDU 3667.Transportation 最小费用流
Transportation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 4067 hdoj 4067 Random Maze 最小费用流
给出n个点,m条边,入口s和出口t,对于每条边有两个值a,b,如果保留这条边需要花费:否则,移除这条边需要花费b. 题目要求用最小费用构造一个有向图满足以下条件: 1.只有一个入口和出口 2.所有路都 ...
随机推荐
- 用DataBaseMail发图片并茂的邮件
不知道各位的老板有没有这样的要求, 一些系统中的数据需要定时发出邮件提醒, 如呆料就要到期或者一些待办的事项提醒. 当然这些用SSRS报表订阅可以实现,但有些公司没有设定相应的报表服务,又或者只是一些 ...
- APK扩展文件及使用
转自:http://blog.csdn.net/myarrow/article/details/7760579 一.APK扩展文件基本知识 Android Market (Google Play St ...
- 【6】连续序列和为s
题目:输入一个整数s,打印出全部和为s的连续整数序列(至少含有2个数).比如输入9,则输出2.3.4和4.5两个序列 方案一:因为序列至少要2个数,则两个数上限值为(1+s)/2,我们能够枚举该序列的 ...
- hdu 5268 ZYB loves Score 水题
ZYB loves Score Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- 你应该知道的c# 反射详解
C#反射 首先了解C#反射的概念,反射是一个运行库类型发现的过程.通过反射可以得到一个给定程序集所包含的所有类型的列表, 这个列表包括给定类型中定义的方法.字段.属性和事件.也可以动态的发现一组给定类 ...
- sql server常用知识点
--删除表 use [20130823_Recource] go drop table my_table1,my_table2,My_table3 --创建表 use [20130823_Recour ...
- 了解javascript中的this --实例篇
对javascript this的赋值有了深一层的理解后,看一下比较复杂的情况,this的应用篇参考<对javascript this的理解>. #demo1 var name=" ...
- SQL SERVER-Delete和Truncate的区别
背景: 一般在删除表数据时候,通常会有执行两个SQL语句:delete和truncate,有条件的删除我们平时都会用delete,而如果全部删除,那我们通常都会选择truncate,因为这 ...
- java中无符号类型的处理
在Java中,不存在Unsigned无符号数据类型,但可以轻而易举的完成Unsigned转换. 方案一:如果在Java中进行流(Stream)数据处理,可以用DataInputStream类对Stre ...
- Golang学习 - unicode/utf16 包
------------------------------------------------------------ // IsSurrogate 判断 r 是否为代理区字符 // 两个代理区字符 ...