Problem Description
Some locations in city A has been destroyed in the fierce battle. So the government decides to send some workers to repair these locations. There are m kinds of workers that were trained for different skills. Each location need some
number of some kinds of workers and has a schedule that at what time can the repair begins, and the time cost of repair. Any job cannot begin until all the workers required arrived.
For example, location 1 needs 2 workers of type 1 and 3 workers of type 2, and the beginning time and time cost is 100 minute and 90 minute correspondingly, then 5 workers that satisfy the requirement should arrive before 100 minute, start working at 100 minute and get the job done at 190 minute. Notice that two different types of workers cannot replace each other, so with 3 workers of type 1 and only 2 workers of type 2, this job cannot be done.
Workers can go from one location to another after their jobs are done. You can take the Euclidean distance between locations as the time workers need to travel between them. Each worker should be sent from a depot initially at 0 minute. Now your task is to determine the minimum number of workers needed to be sent from depot so that all the jobs can be done.
For example, location 1 needs 2 workers of type 1 and 3 workers of type 2, and the beginning time and time cost is 100 minute and 90 minute correspondingly, then 5 workers that satisfy the requirement should arrive before 100 minute, start working at 100 minute and get the job done at 190 minute. Notice that two different types of workers cannot replace each other, so with 3 workers of type 1 and only 2 workers of type 2, this job cannot be done.
Workers can go from one location to another after their jobs are done. You can take the Euclidean distance between locations as the time workers need to travel between them. Each worker should be sent from a depot initially at 0 minute. Now your task is to determine the minimum number of workers needed to be sent from depot so that all the jobs can be done.
Input
There are multiple test cases, the integer on the first line T (T<25) indicates the number of test cases.
Each test case begins with two integers n (<=150), the number of location(including the depot) and m(<=5), the number of different skills.
The next line gives two integers x0, y0 indicates the coordinate of depot.
Then follows n - 1 lines begins with 4 integer numbers: xi, yi, bi(bi>0), pi(pi>0), (xi, yi) gives the coordinate of the i-th location, bi gives the beginning time and pi gives the time cost. The rest of the line gives m non-negative integers v1, v2, ..., vm, of which the i-th number indicates the the number of workers of type i needed (for all vi, 0<=vi<10, each location at least requires one worker).
All integers are less than 1000000 (106).
Each test case begins with two integers n (<=150), the number of location(including the depot) and m(<=5), the number of different skills.
The next line gives two integers x0, y0 indicates the coordinate of depot.
Then follows n - 1 lines begins with 4 integer numbers: xi, yi, bi(bi>0), pi(pi>0), (xi, yi) gives the coordinate of the i-th location, bi gives the beginning time and pi gives the time cost. The rest of the line gives m non-negative integers v1, v2, ..., vm, of which the i-th number indicates the the number of workers of type i needed (for all vi, 0<=vi<10, each location at least requires one worker).
All integers are less than 1000000 (106).
Output
For each test cases output one line, the minimum workers to be sent. It is guaranteed that there's always a feasible solution that all the jobs can be done.
Sample Input
2 4 1 0 0 0 1 1 1 3 1 1 3 3 4 1 0 10 1 5 4 1 0 0 0 1 1 1 3 1 1 3 3 4 1 0 3 1 5
Sample Output
5 9
一个地点拆成三个点,i、i’、i”
S -> i : 容量为type[i][k],费用为1.
i -> i’ : 容量为type[i][k],费用为0.
i’ -> T : 容量为type[i][k],费用为0. S -> i” : 容量为type[i][k],费用为0.
如果工人可以在地点i工作完成后到达地点j开工,建边i” -> j’ : 容量为v[i][k],费用为0. 相当于j点的流量减小了v[i][k]。
最小路径覆盖模型
可行流的最小流? 网络流解法有待完善
#include<bits/stdc++.h>
#define mem(a,x) memset(a,x,sizeof(a))
#define lp(k,a) for(int k=1;k<=a;k++)
#define lp0(k,a) for(int k=0;k<a;k++)
#define lpn(k,n,a) for(int k=n;k<=a;k++)
#define lpd(k,n,a) for(int k=n;k>=a;k--)
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d %d",&a,&b)
#define MAX 100000
using namespace std;
#define ll int
#define inf 0x3f3f3f3f
//#define inf 999999999
//#define Inf 0x3FFFFFFFFFFFFFFFLL
#define N 500
#define M 50000
int x00,y00;
struct Point
{
int x,y,b,p;
int type[10];
}point[160],point0;
struct Edge
{
ll to,cap,cost,nex;
Edge() {}
Edge(ll to,ll cap,ll cost,ll next):to(to),cap(cap),cost(cost),nex(next) {}
} edge[M];
ll head[N],top;
ll D[N],A[N],P[N],li[N];
bool inq[N];
double dis(Point p1,Point p2)
{
return (sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
}
void add(ll from,ll to,ll cap,ll cost)
{
edge[top]=Edge(to,cap,cost,head[from]);
head[from]=top++;
edge[top]=Edge(from,0,-cost,head[to]);
head[to]=top++;
}
bool spfa(ll s,ll t,ll &flow,ll &cost)
{
for(ll i=0; i<=t; i++) D[i]=inf;
mem(inq,0);
queue<ll>q;
q.push(s);
D[s]=0;
A[s]=inf;
while(!q.empty())
{
ll u=q.front();
q.pop();
inq[u]=0;
for(ll i=head[u]; ~i; i=edge[i].nex)
{
Edge &e=edge[i];
if(e.cap && D[e.to]>D[u]+e.cost)
{
D[e.to]=D[u]+e.cost;
P[e.to]=i;
A[e.to]=min(A[u],e.cap);
if(!inq[e.to])
{
inq[e.to]=1;
q.push(e.to);
}
}
}
}
if(D[t]==inf) return false;
cost+=D[t]*A[t];
flow+=A[t];
ll u=t;
while(u!=s)
{
edge[P[u]].cap-=A[t];
edge[P[u]^1].cap+=A[t];
u=edge[P[u]^1].to;
}
return true;
}
ll mcmf(ll s,ll t)
{
ll flow=0, cost=0;
while(spfa(s,t,flow,cost));
return cost;
}
int S,T,n,m,cnt;
void init(int TYPE)
{
mem(head,-1);
cnt=0;
top=0;
S=0;
T=3*n+1;
lp(i,n)
{
//if(point[i].b >= dis(point0,point[i]))
{
add(S,i,point[i].type[TYPE],1);
add(S,i+2*n,point[i].type[TYPE],0);
}
add(i,i+n,point[i].type[TYPE],0);
add(i+n,T,point[i].type[TYPE],0);
}
lp(i,n)
lp(j,n)
{
if(i==j) continue;
if((dis(point[i],point[j])+point[i].b+point[i].p) <= point[j].b)
{
//cout<<"i="<<i<<" "<<j<<endl;
add(i+2*n,j+n,point[i].type[TYPE],0);
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
int t;
sc(t);
while(t--)
{
int re=0;
sc2(n,m);
sc2(x00,y00);
point0.x=x00;
point0.y=y00;
lp(i,n-1)
{
sc2(point[i].x,point[i].y);
sc2(point[i].b,point[i].p);
lp(j,m)
{
sc(point[i].type[j]);
}
}
n--;
lp(i,m)
{
init(i);
re+=mcmf(S,T);
}
printf("%d\n",re);
}
return 0;
}