【网络流24题】深海机器人问题

来源:互联网 发布:网络机顶盒占用网速 编辑:程序博客网 时间:2024/04/29 00:54

(网络流24题大多需要spj,所以需要一个有spj的oj,本系列代码均在www.oj.swust.edu.cn测试通过)
这道题其实和数字梯形的第三个规律挺像的(点和路径均可重合),唯一的差别就是这道题的路径权值只能计算一次,那怎么办呢,其实不难,我们只要将容量为INF的边的权值修改为0,在此基础上再加一条容量为1,权值为给定权值的边即可。跑一边最大费用最大流就可以啦。

#include<cstdio>#include<cstdlib>#include<cmath>#include<ctime>#include<cstring>#include<string>#include<iostream>#include<iomanip>#include<algorithm>using namespace std;#define INF 100000000int dis[10000];bool pd[10000];int fro[10000];int s=0,t=9999;struct bian{    int l,r,v,f;}a[1000000];int fir[1000000];int nex[1000000];int tot=1;void add_edge(int l,int r,int f,int v){    a[++tot].l=l;    a[tot].r=r;    a[tot].f=f;    a[tot].v=v;    nex[tot]=fir[l];    fir[l]=tot;}bool spfa(){    static int dui[1000000];    memset(dis,0x8f,sizeof(dis));    int top=1,my_final=2;    dui[top]=s;    dis[s]=0;    pd[s]=true;    while(top<my_final)    {        int u=dui[top++];        for(int o=fir[u];o;o=nex[o])        {            if(dis[a[o].r]<dis[u]+a[o].v && a[o].f)            {                dis[a[o].r]=dis[u]+a[o].v;                fro[a[o].r]=o;                if(!pd[a[o].r]) pd[a[o].r]=true,dui[my_final++]=a[o].r;            }        }        pd[u]=false;    }    if(dis[t]==0x8f8f8f8f) return false;    return true;}int cost;void add_flow(){    int mid=t;    int temp=2147483647;    while(mid!=s)    {        temp=min(temp,a[fro[mid]].f);        mid=a[fro[mid]^1].r;    }    cost+=temp*dis[t];    mid=t;    while(mid!=s)    {        a[fro[mid]].f-=temp;        a[fro[mid]^1].f+=temp;        mid=a[fro[mid]^1].r;    }}int val[100][100];int n,m;inline int wz(int x,int y){    return (x-1)*m+y;}int main(){    int st,fi;    scanf("%d%d",&st,&fi);    scanf("%d%d",&n,&m);    n++,m++;    for(int i=1;i<=n;i++)        for(int j=1;j<m;j++)        {            int x;            scanf("%d",&x);            add_edge(wz(i,j),wz(i,j+1),1,x);            add_edge(wz(i,j+1),wz(i,j),0,-x);            add_edge(wz(i,j),wz(i,j+1),INF,0);            add_edge(wz(i,j+1),wz(i,j),0,0);        }    for(int i=1;i<=m;i++)        for(int j=1;j<n;j++)        {            int x;            scanf("%d",&x);            add_edge(wz(j,i),wz(j+1,i),1,x);            add_edge(wz(j+1,i),wz(j,i),0,-x);            add_edge(wz(j,i),wz(j+1,i),INF,0);            add_edge(wz(j+1,i),wz(j,i),0,0);        }    for(int i=1;i<=st;i++)    {        int x,y,k;        scanf("%d%d%d",&k,&x,&y);        x++,y++;        add_edge(s,wz(x,y),k,0);        add_edge(wz(x,y),s,0,0);    }    for(int i=1;i<=fi;i++)    {        int x,y,k;        scanf("%d%d%d",&k,&x,&y);        x++,y++;        add_edge(wz(x,y),t,k,0);        add_edge(t,wz(x,y),0,0);    }    while(spfa()) add_flow();    cout<<cost;    return 0;}
0 1
原创粉丝点击