题意:

      给你一些任务,每个任务有自己的开始时间和需要多久能干完,还有就是每个任务都需要一些人,这些人有最多五个种类,各种类之间的人不能相互替换,但是某些工人干完这个活后如果可以在另一个任务还没开始的时候赶过去,也可以帮那个任务干活,干的是自己的属性的活,还有一个关键的点就是所有的任务必须人齐了才能干,最后问你最少要多少个人能把活干完..

思路:

      费用流,就是在满流(任务都必须干完)的前提下花费最少,一开始想的是吧每个点先拆成五个点,代表不同属性的人,sb了,写来写去自己都蒙了,其实每个属性的人之间没有关系的话我们可以单独算啊,就是跑5变费用流被,最后把他们加起来就好了,这样就很容易写了,下面说重点,怎么建图.

首先要有一个超级源点和汇点,不解释..

然后就是对于每一个点,我们要拆成两个点(这两个点之间没有边),这两个点不是平时我们那种限流的点,一个是自己,另一个是用来连接自己可以给别的任务送人用的..对于每一个自己的点,我们连一条边,流量inf,费用1,很容易理解,总部有无数的人,但是你要是用一个就得付出一个代价..

然后就是对于每一个拆出来的点,原点像它连接一条边,流量是need,费用是0,因为当前的这个点最多能给别人提供need的人,而且是免费的...

最后就是找任务个任务之间的关系了,如果 work[i].p + work[i].d + dis(i ,j) <= work[j].p ,就还来的及,那么就用i拆出来的那个点,去连接j的那个点...


大概就是这个样子,自己表达能力不好,如果没看懂画一下子就明白了... 


#include<stdio.h>
#include<string.h>
#include<queue>
#include<math.h> #define N_node 350
#define N_edge 30000
#define inf 1000000000

using namespace
std; typedef struct
{
int
from ,to ,cost ,flow ,next;
}
STAR; typedef struct
{
double
x ,y;
int
p ,d;
int
need[6];
}
WORK; STAR E[N_edge];
WORK work[N_node];
int
list[N_node] ,tot;
int
mer[N_edge]; void add(int a ,int b ,int c ,int d)
{

E[++tot].from = a;
E[tot].to = b;
E[tot].cost = c;
E[tot].flow = d;
E[tot].next = list[a];
list[a] = tot;
} bool
spfa(int s ,int t ,int n)
{
int
s_x[N_node];
for(int
i = 0 ;i <= n ;i ++)
s_x[i] = inf;
int
mark[N_node] = {0};
s_x[s] = 0;
mark[s] = 1;
queue<int>q;
q.push(s);
memset(mer ,255 ,sizeof(mer));
while(!
q.empty())
{
int
tou ,xin;
tou = q.front();
q.pop();
mark[tou] = 0;
for(int
k = list[tou] ;k ;k = E[k].next)
{

xin = E[k].to;
if(
E[k].flow && s_x[xin] > s_x[tou] + E[k].cost)
{

s_x[xin] = s_x[tou] + E[k].cost;
mer[xin] = k;
if(!
mark[xin])
{

mark[xin] = 1;
q.push(xin);
}
}
}
}
return
mer[t] != -1;
} int
M_C_flow(int s, int t, int n)
{
int
ans = 0 ,minflow;
int
maxflow = 0;
while(
spfa(s ,t ,n))
{

minflow = inf;
for(int
i = mer[t] ;i + 1 ;i = mer[E[i].from])
{
if(
minflow > E[i].flow)
minflow = E[i].flow;
}
for(int
i = mer[t] ;i + 1 ;i = mer[E[i].from])
{

E[i].flow -= minflow;
E[i^1].flow += minflow;
ans += E[i].cost * minflow;
}

maxflow += minflow;
}
return
ans;
} int main ()
{
int
t ,n ,m ,i ,j;
double
sx ,sy;
int
a ,b, c ,d;
scanf("%d" ,&t);
while(
t--)
{

scanf("%d %d" ,&n ,&m);
scanf("%lf %lf" ,&sx ,&sy);
n --;
for(
i = 1 ;i <= n ;i ++)
{

scanf("%lf %lf %d %d" ,&work[i].x ,&work[i].y ,&work[i].p ,&work[i].d);
for(
j = 1 ;j <= m ;j ++)
scanf("%d" ,&work[i].need[j]);
}
int
ans = 0;
for(int
ii = 1 ;ii <= m ;ii ++)
{

memset(list ,0 ,sizeof(list));
tot = 1;
int
s = 0 ,t = n * 2 + 1;
for(
i = 1 ;i <= n ;i ++)
{

add(s ,i ,1 ,inf) ,add(i ,s ,-1 ,0);
add(i ,t ,0 ,work[i].need[ii]) ,add(t ,i ,-0 ,0);
add(s ,i + n ,0 ,work[i].need[ii]) ,add(i + n ,s ,-0 ,0);
}
for(
i = 1 ;i <= n ;i ++)
for(
j = 1 ;j <= n ;j ++)
{
if(
i == j) continue;
double
dis = pow(work[i].x - work[j].x ,2.0) + pow(work[i].y - work[j].y ,2.0);
dis = sqrt(dis);
if(
work[i].p + work[i].d + dis <= work[j].p)
add(i + n ,j ,0 ,inf) ,add(j ,i + n ,-0 ,0);
}

ans += M_C_flow(0 ,t ,t);
}

printf("%d\n" ,ans);
}
return
0;
}

hdu4494的更多相关文章

  1. Teamwork[HDU4494]

    Teamwork Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submi ...

随机推荐

  1. springmvc字符 中文乱码问题

    springmvc字符 中文乱码问题 1.字符过滤器 输入中文测试,发现乱码 以前乱码问题通过过滤器解决 , 而SpringMVC给我们提供了一个过滤器 , 可以在web.xml中配置,修改了xml文 ...

  2. HDOJ-6656(数论+逆元)

    Kejin Player HDOJ-6656 设f[i]为从i升级到i+1期望需要的金钱,由于每级都是能倒退或者升级到i+1,所以询问从l,r的期望金钱可以直接前缀和,那么推导每一级升级需要的期望钱也 ...

  3. [笔记] CRT & exCRT

    [笔记] CRT & exCRT 构造法 求多组\(x \equiv r_i (\bmod d_i)\)的解,\(d_i\)互质 余数\((r_i = remainder)\),除数\((d_ ...

  4. 1-认识c指针

    1.指针和内存 c程序在编译后,会以三种形式使用内存 1静态/全局内存 静态声明的变量分配在这里,全局变量也使用这部分内存.这些变量在程序开始运行时分配,直到程序终止时才会消失 2.自动内存 这些变量 ...

  5. [系统重装日志1]快速迁移/恢复Mendeley的文献和笔记

    一时手贱把原先系统的EFI分区给删了,按照网上的教程还没有恢复成功,无奈之下只能重装系统,想想这么多环境和配置真是酸爽. 身为一个伪科研工作者,首先想到的是自己的文献和阅读笔记.我所使用的文献管理工具 ...

  6. c++ vector容器浅析

    注:本文章参考 https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html 前言: 最近遇到一个广搜的题,不管怎么试都会暴 然后 ...

  7. Vue3教程:Vue 3 + Element Plus + Vite 2 的后台管理系统开源啦

    之前发布过一篇文章<Vue3教程:开发一个 Vue 3 + element-plus 的后台管理系统>,文中提到会开发并开源一个 Vue 3 + Element Plus 的项目供大家练手 ...

  8. 全网最详细的Linux命令系列-nl命令

    nl命令在linux系统中用来计算文件中行号.nl 可以将输出的文件内容自动的加上行号!其默认的结果与 cat -n 有点不太一样, nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 等 ...

  9. 201871010130-周学铭 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接 18卓越班 这个作业要求链接 实验三结对编程要求 我的课程学习目标 体验软件项目开发中的两人合作,练习结对编程(Pair programming).掌握Github协作开 ...

  10. Dynamics CRM与ADFS安装到同一台服务器后ADFS服务与Dynamics CRM沙盒服务冲突提示808端口占用问题

    当我们安装Dynamics CRM的产品时如果是单台服务器部署而且部署了IFD的情况会遇到一个问题就是ADFS服务的监听端口和Dynamics CRM沙盒服务的端口冲突了. 这样会导致两个服务中的一个 ...