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

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

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 100000000
int 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(topint u=dui[top++];
        for(int o=fir[u];o;o=nex[o])
        {
            if(dis[a[o].r]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;jint 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;jint 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<return 0;
}

你可能感兴趣的:(网络流,费用流)