HDU 4494 Teamwork 2013通化邀请赛 B题 费用流

来源:互联网 发布:日本三河黑松淘宝网 编辑:程序博客网 时间:2024/05/02 00:23
#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.csdn.net/yrleep/article/details/13391427

原创粉丝点击