hdu4494
题意:
给你一些任务,每个任务有自己的开始时间和需要多久能干完,还有就是每个任务都需要一些人,这些人有最多五个种类,各种类之间的人不能相互替换,但是某些工人干完这个活后如果可以在另一个任务还没开始的时候赶过去,也可以帮那个任务干活,干的是自己的属性的活,还有一个关键的点就是所有的任务必须人齐了才能干,最后问你最少要多少个人能把活干完..
思路:
费用流,就是在满流(任务都必须干完)的前提下花费最少,一开始想的是吧每个点先拆成五个点,代表不同属性的人,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的更多相关文章
- Teamwork[HDU4494]
Teamwork Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submi ...
随机推荐
- macOS启动Kafka
目录 kafka目录结构 先启动zookeeper 后启动kafka 创建topic 创建一个生产者 创建一个消费者 kafka目录结构 # kafka安装目录 /usr/local/Cellar/k ...
- Docker安装开发环境
目录 Docker Docker 安装 Mysql Docker 安装Redis Docker 安装Zookeeper Docker Docker 安装 Mysql Docker 查看可用Mysql镜 ...
- 从sql语句的角度解刨SqlServer插入语句的并发问题
今天收到一个小学弟的求助,数据库插入偶尔重复,怎么在sql语句上进行解决. Q:学长,我导入excel数据的操作,平时使用好好的,怎么突然发生插入重复的问题? A:你是使用哪个ORM框架进行操作的? ...
- 三分钟教你提升应用推送的ROI
推送是App应用性价比最高也是最直接的营销运营手段,其细节颇多,非常考验运营人员的功力,本文将从ROI角度来分析怎么提升营销类推送的收益.(非IM类.系统类等功能服务型推送) 以一个日活100万的应用 ...
- MongoDB学习--环境搭建记录
Mongo安装教程,参考英文官网 基本命令, 索引的引用,索引基于地理位置的数据, win10 64位 系统中安装虚拟机 win10 系统中安装虚拟机VMwareWorkstation11 并安装 L ...
- android 调用js,js调用android
Java调用JavaScript 1.main.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?xml v ...
- Xshell(远程)连接不上linux服务器(防火墙介绍)
一.原因 远程(ssh)连接不上linux服务器的大多数原因都是因为本地服务器的防火墙策略导致的,因此我们想ssh远程能够连接上服务器,有两种方法: 修改防火墙策略 关闭防火墙 二.防火墙服务介绍 1 ...
- Spring Native 项目,把 Spring 项目编译成原生程序!
Spring Native 是什么 优点 缺点 原生镜像(native image)和常规 JVM 程序的区别 前置条件:GraalVM 支持的语言 关键特性 GraalVM 下的 Java 微服务 ...
- java例题_18 乒乓球比赛(对手问题)
1 /*18 [程序 18 乒乓球赛] 2 题目:两个乒乓球队进行比赛,各出三人.甲队为 a,b,c 三人,乙队为 x,y,z 三人.已抽签决定比赛名单. 3 有人向队员打听比赛的名单.a说他不和 x ...
- 日志文件删除shell脚本
大日志文件切割shell脚本 #!/bin/bash # --------------------------------------------------------------------- # ...