[NOIP提高组2000]方格取数

来源:互联网 发布:c语言数组和指针的区别 编辑:程序博客网 时间:2024/05/21 06:43

记得很久以前做的时候,这题是一个恶心的DP。。
然后当时觉得难得要死。。
然后今天一看,DP没有弄,一看就是费用流裸题嘛。。
MDZZ,费用流不用脑子,想什么DP啊
然后就打。。
空间写挫了。。
然后改了改,A了
构图看代码

#include<cstdio>#include<queue>#include<algorithm>#include<cstring>#include<iostream>#include<cstring>using namespace std;const int N=12*12*2;const int MAX=1<<30;int x,y,z;int n;struct qq{    int x,y,z,z1,last;//流量    费用 }s[N*N*2];int num,last[N];int st,ed;void init (int x,int y,int z,int z1){    num++;    s[num].x=x;s[num].y=y;s[num].z=z;s[num].z1=z1;    s[num].last=last[x];    last[x]=num;    swap(x,y);z=0;z1=-z1;    num++;    s[num].x=x;s[num].y=y;s[num].z=z;s[num].z1=z1;    s[num].last=last[x];    last[x]=num;}int from[N];int f[N];bool in[N];bool SPFA (){    memset(in,false,sizeof(in));    memset(from,-1,sizeof(from));    memset(f,-1,sizeof(f));    queue<int> q;    q.push(st);    f[st]=0;in[st]=true;    while (!q.empty())    {        int x=q.front();q.pop();        for (int u=last[x];u!=-1;u=s[u].last)        {            int y=s[u].y;            if (s[u].z>0&&f[y]<f[x]+s[u].z1)            {                f[y]=f[x]+s[u].z1;                from[y]=u;                if (in[y]==false)                {                    in[y]=true;                    q.push(y);                }            }        }        in[x]=false;    }    return from[ed]!=-1;}int mymin (int x,int y){    return x<y?x:y;}int ans=0;void lalal (){    int x=from[ed],t=MAX;    while (x!=-1)    {        t=mymin(t,s[x].z);        x=from[s[x].x];    }    x=from[ed];    while (x!=-1)    {        ans=ans+t*s[x].z1;        s[x].z-=t;        s[x^1].z+=t;        x=from[s[x].x];    }    return ;}int Get (int x,int y){    return (x-1)*n+y;}int main(){    num=1;memset(last,-1,sizeof(last));    scanf("%d",&n);    st=n*n*2+1;ed=st+1;    while (true)    {        scanf("%d%d%d",&x,&y,&z);        if (x==0) break;        init(Get(x,y),Get(x,y)+n*n,1,z);    }    for (int u=1;u<=n;u++)        for (int i=1;i<=n;i++)        {            if (u+1<=n)//往下是可以的             {                init(Get(u,i)+n*n,Get(u+1,i),MAX,0);            }            if (i+1<=n)            {                init(Get(u,i)+n*n,Get(u,i+1),MAX,0);            }            init(Get(u,i),Get(u,i)+n*n,MAX,0);        }    init(st,Get(1,1),2,0);    init(Get(n,n)+n*n,ed,2,0);    while (SPFA()==true)         lalal();    printf("%d\n",ans);    return 0;}
原创粉丝点击