#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
const int maxn=500;
const int inf=1<<30;
double dist[maxn][maxn];
int x[maxn],y[maxn],star[maxn],p[maxn],a[maxn][10];
struct edge
{
int u,v,c,w,next;
}e[maxn*maxn];
int tot;
int head[maxn];
int from[maxn];
bool vis[maxn];
int queue[maxn*maxn],d[maxn];
int n,m;
double dis(int i,int j)
{
return sqrt(((double)x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
void add(int u,int v,int c,int w)//加边,u->v,流量c,花费w;
{
tot++;
e[tot].u=u;
e[tot].v=v;
e[tot].c=c;
e[tot].w=w;
e[tot].next=head[u];
head[u]=tot;
}
bool spfa(int star,int end)
{
for (int i=star;i<=end;i++)
d[i]=inf;
memset(vis,0,sizeof(vis));
memset(from,-1,sizeof(from));//到达该点的流从哪条边流进的;
int h=0,t=1;//队列的头尾指针;
d[star]=0;//到达该点的最小花费;
vis[star]=1;//是否入队的标记;
queue[1]=star;//队列;
while(h<t)
{
h++;
int u=queue[h];
for(int i=head[u];i!=-1;i=e[i].next)
if(e[i].c>0)
{
int v=e[i].v,w=e[i].w;
if(d[v]>d[u]+w)
{
d[v]=d[u]+w;
from[v]=i;
if(!vis[v])
{
vis[v]=1;
t++;
queue[t]=v;
}
}
}
vis[u]=0;
}
return from[end]!=-1;
}
int maxflow(int s,int t)//网络流的s点,t点的编号;
{
int ans=0;
int flow=0;
while(spfa(s,t))
{
for(int i=from[t];i!=-1;i=from[e[i].u])//倒推找到的流量最小的流;
{
e[i].c--;
e[i^1].c++;
ans+=e[i].w;
}
flow++;
}
return ans;//返回值是最大流的最小费用;
//return flow;
}
int main()
{
int t;
int x0,y0;
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
scanf("%d%d",&x0,&y0);
for (int i=1;i<n;i++)
{
scanf("%d%d%d%d",&x[i],&y[i],&star[i],&p[i]);
for (int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
}
for (int i=1;i<n;i++)
for (int j=i+1;j<n;j++)
dist[i][j]=dist[j][i]=dis(i,j);
int ans=0;
n--;
for (int j=1;j<=m;j++)
{
tot=-1;
memset(head,-1,sizeof(head));
for (int i=1;i<=n;i++)
{
add(0,i,a[i][j],1);
add(i,0,0,-1);
add(i,i+n*2,a[i][j],0);
add(i+n*2,i,0,0);
add(i+n*2,3*n+1,a[i][j],0);
add(3*n+1,i+n*2,0,0);
add(0,i+n,a[i][j],0);
add(i+n,0,0,0);
}
for (int i=1;i<=n;i++)
for (int k=1;k<=n;k++)
if (i!=k)
{
if (star[i]+p[i]+dist[i][k]<=star[k])
{
add(i+n,k+2*n,min(a[i][j],a[k][j]),0);
add(k+2*n,i+n,0,0);
}
}
ans+=maxflow(0,3*n+1);
}
printf("%d\n",ans);
}
return 0;
}
看来学长的另一种做法,觉得也不错,给大家推荐一下http://blog.youkuaiyun.com/yrleep/article/details/13391427