zoukankan      html  css  js  c++  java
  • FTR #1 百步穿杨

    一定要纪念这一天。

    我这题调了整整一天。。。。。

    2333

    大概错了一个小地方,然后是两个建图的错误。

    一是拆点,二是inf的是单向边。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define maxn 55
    #define maxv 100050
    #define maxe 10000050
    #define inf 1000000007
    using namespace std;
    int n,m,map[maxn][maxn],dis[maxv],nume=1,g[maxv],tot=0,lab[maxn][maxn],tab[maxv],max_flow=0;
    int stack[maxv],top=0,s,t,cnt=0;
    int s1[maxv],s2[maxv],t1=0,t2=0,cnts[maxn][maxn];
    bool vis[maxn*maxn][maxn][maxn];
    struct edge
    {
        int v,f,nxt;
    }e[maxe];
    struct point
    {
        int x,y,d;
        point (int x,int y,int d):x(x),y(y),d(d) {}
        point () {}
    }p[maxv],en[maxv];
    queue <int> q;
    int dx[]={0,-1,1,0,0},dy[]={0,0,0,-1,1};
    char ss[maxn];
    void addedge(int u,int v,int f)
    {
        e[++nume].v=v;e[nume].f=f;
        e[nume].nxt=g[u];g[u]=nume;
        e[++nume].v=u;e[nume].f=0;
        e[nume].nxt=g[v];g[v]=nume;
    }
    bool judge(int x,int y)
    {
        return ((x>=1) && (x<=n) && (y>=1) && (y<=m) && (map[x][y]>=0));
    }
    void build(int xx)
    {
        top=0;
        int x=p[xx].x,y=p[xx].y,d=p[xx].d,mx=0;
        if (d<=2) stack[++top]=s;else stack[++top]=t;
        if (judge(x+dx[d],y+dy[d]))
        {
            do
            {
                x+=dx[d];y+=dy[d];
                if (map[x][y]>mx) {mx=map[x][y];stack[++top]=lab[x][y];en[xx]=point(x,y,0);vis[xx][x][y]=true;}
            }while (judge(x+dx[d],y+dy[d]));
            if (d<=2) for (int i=1;i<=top-1;i++) addedge(stack[i],stack[i+1],mx-tab[stack[i]]);
            else for (int i=1;i<=top-1;i++) addedge(stack[i+1]+cnt,stack[i]+cnt*(i!=1),mx-tab[stack[i]]);
            max_flow+=mx;
        }
    }
    void cross(int x,int y)
    {
        if ((max(p[x].d,p[y].d)<=2) || (min(p[x].d,p[y].d)>=3)) return;
        t1=0;t2=0;int xx,yy,d,retx=-1,rety=-1,pp=-1,qq=-1;
        int ex1,ey1,ex2,ey2;
        xx=p[x].x;yy=p[x].y;d=p[x].d;
        if (judge(xx+dx[d],yy+dy[d]))
        {
            do 
            {
                xx+=dx[d];yy+=dy[d];
                cnts[xx][yy]++;
                if ((xx==en[x].x) && (yy==en[x].y)) break;
            }while (judge(xx+dx[d],yy+dy[d]));
        }
        ex1=xx;ey1=yy;
        xx=p[y].x;yy=p[y].y;d=p[y].d;
        if (judge(xx+dx[d],yy+dy[d]))
        {
            do
            {
                xx+=dx[d];yy+=dy[d];cnts[xx][yy]++;
                if (cnts[xx][yy]==2) retx=xx,rety=yy;
                if ((xx==en[y].x) && (yy==en[y].y)) break;
            }while (judge(xx+dx[d],yy+dy[d]));
        }
        ex2=xx;ey2=yy;
        int flag1=0,flag2=0;
        while ((ex1!=p[x].x) || (ey1!=p[x].y))
        {
            cnts[ex1][ey1]--;
            if ((map[ex1][ey1]) && (!flag1) && (retx!=-1) && (rety!=-1) && (vis[x][ex1][ey1])) pp=lab[ex1][ey1];
            if ((ex1==retx) && (ey1==rety)) flag1=1;
            ex1-=dx[p[x].d];ey1-=dy[p[x].d];
        }
        while ((ex2!=p[y].x) || (ey2!=p[y].y))
        {
            cnts[ex2][ey2]--;
            if ((map[ex2][ey2]) && (!flag2) && (retx!=-1) && (rety!=-1) && (vis[y][ex2][ey2])) qq=lab[ex2][ey2];
            if ((ex2==retx) && (ey2==rety)) flag2=1;
            ex2-=dx[p[y].d];ey2-=dy[p[y].d];
        }
        if ((pp==-1) || (qq==-1)) return;
        if (p[x].d>=3) swap(pp,qq);
        addedge(pp,qq+cnt,inf);
    }
    bool bfs()
    {
        q.push(s);
        for (int i=s;i<=t;i++) dis[i]=inf;
        dis[s]=0;
        while (!q.empty())
        {
            int head=q.front();q.pop();
            for (int i=g[head];i;i=e[i].nxt)
            {
                int v=e[i].v;
                if ((e[i].f>0) && (dis[v]>dis[head]+1))
                {
                    dis[v]=dis[head]+1;
                    q.push(v);
                }
            }
        }
        return dis[t]!=inf;
    }
    int dinic(int x,int low)
    {
        if (x==t) return low;
        int ret=0;
        for (int i=g[x];low && i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (e[i].f>0 && dis[v]==dis[x]+1)
            {
                int dd=dinic(v,min(low,e[i].f));
                ret+=dd;low-=dd;
                e[i].f-=dd;e[i^1].f+=dd;
            }
        }
        if (!ret) dis[x]=inf;
        return ret;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
        {
            scanf("%s",ss);
            for (int j=1;j<=m;j++)
            {
                if ((ss[j-1]>='0') && (ss[j-1]<='9')) map[i][j]=ss[j-1]-'0';
                else if (ss[j-1]=='.') map[i][j]=0;
                else
                {
                    map[i][j]=-1;
                    if (ss[j-1]=='A') p[++tot]=point(i,j,1);
                    else if (ss[j-1]=='V') p[++tot]=point(i,j,2);
                    else if (ss[j-1]=='<') p[++tot]=point(i,j,3);
                    else p[++tot]=point(i,j,4);
                }
            }
        }
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                if (map[i][j]>0) lab[i][j]=++cnt,tab[cnt]=map[i][j];
        s=0;t=2*cnt+1;
        for (int i=1;i<=tot;i++) build(i);
        for (int i=1;i<=tot;i++)
                for (int j=i+1;j<=tot;j++)
                    cross(i,j);
        while (bfs())
                max_flow-=dinic(s,inf);
        printf("%d
    ",max_flow);
        return 0;
    }
  • 相关阅读:
    当前疫情期间,家里可以适当储备的物资
    35岁改行做程序员,需要勇气和决心
    离婚潮来临,女性在崛起
    摄影作品首先要取悦自己,更要打动他人
    京剧是该阳春白雪还是下里巴人?
    汶川和武汉哪个更让人铭记?
    35以上的女强人不结婚,只用平常待之
    苏州记忆之上班路上偶遇2美女打架
    SAP SD微观研究之销售发票自动生成初探
    Python requests库的使用(二)
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6480601.html
Copyright © 2011-2022 走看看