P4066 [SHOI2003] eat peas

  This question and I encounter, is that graceful Friday night in.

  As a simulation title, she was well performed her duties, will not let me ......

  Closer to home ...

  In fact, from the simulation end of 14 minutes when I came up with the wording of cost flow ...... (70 points), but obviously I did not write for some time network flow, coupled with the time is too short, did not go to write.

  This question and passing notes like ah ...... I began to consider dp, but the range is too big, can not then start ...... then I thought - not that the point on which the two paths most thing? For not cross, we can think of to limit network traffic flow.

  So - maximum flow maximum fee.

  For a point can only be selected once the limit, conventional flow of the routine are network - point-split edge build capacity of 1, that is to say only this side of both ends in the maximum flow, in order to count the cost . Corresponding fee (equivalent chose this point) is also 1. For each point on the lower left and upper right, even a flow of a cost of the edge between the two points 0. For controlling the flow, we can build two source points, s1 to s2 is even a flow rate of 2 side, how many PACMAN this is the case regardless of departure, we can all be achieved by controlling the capacity of this edge.

  I started it is in accordance with this idea, violent side to build only 70 points. Because then the side of a 2000 * 2000 * 2000 * 2 + 2 + 2 * 2 * 2000, which is too much ...... this dense graph, spfa will not stand.

  Therefore, we consider the optimization:

  For a point (red dot), we observed that point the lower left corner:

 

  

  We found that all of the points the lower left corner, you can reach through the blue dot red dot directly or indirectly. So, we shield the point of these two points and the blue rectangle origin constituted of, even just a red dot blue dot.

  But there may rectangle method is no point to go directly to the blue dot red dot better, so our transfer station - blue dot must take this into account clock situation. Then split into two points to one point, and then connected to a capacity therebetween INF, 0 cost of receiving side : this is equivalent to, the connection point of the two points, two points on the graph after this point connectivity, but nothing to do with this point .

  That is, each have two pairs apart between the points (p) side,

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define maxn 5000005
#define inf 99999999
struct node
{
    int nxt=-1,to,w,flow,cost;
} edge[maxn];
struct xy
{
    int x,y,id;
} po[5000];
int head[maxn],dis[5000],pre[5000];
bool vis[5000];
int s1,s2,t,ans,cnt=-1,n;
bool cmp(xy a,xy b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
void add(int a,int b,int flow,int cost)
{
    edge[++cnt].to=b;
    edge[cnt].w=flow;
    edge[cnt].cost=cost;
    edge[cnt].nxt=head[a];
    head[a]=cnt;
}
int spfa()
{
    for(int i=0; i<=t; i++)
    {
        dis[i]=-inf;
        vis[i]=0;
        pre[i]=-1;
    }
    dis[s1]=0;
    queue<int> Q;
    Q.push(s1);
    vis[s1]=1;
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        vis[u]=0;
        for(int i=head[u]; i!=-1; i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(dis[v]<dis[u]+edge[i].cost&&edge[i].w>edge[i].flow)
            {
                dis[v]=dis[u]+edge[i].cost;
                pre[v]=i;
                if(!vis[v])
                {
                    vis[v]=1;
                    Q.push(v);
                }
            }
        }
    }
    if(pre[t]!=-1) return 1;
    return 0;
}
int maxcost_maxflow()
{
    while(spfa())
    {
        int MIN=inf;
        for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to])
        {
            edge[i].flow+=1;
            edge[i^1].flow-=1;
            ans+=edge[i].cost;
        }
    }
    return ans;
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    s1=0,s2=2*n+1,t=2*n+2;
    for(int i=1; i<=n; i++)
        scanf("%d%d",&po[i].x,&po[i].y);
    sort(po+1,po+n+1,cmp);
    for(int i=n; i>=1; i--)
    {
        add(i,i+n,1,1);
        add(i+n,i,0,-1);
        add(i,i+n,inf,0);
        add(i+n,i,0,0);
        
        add(s2,i,1,0);
        add(i,s2,0,0);
        add(i+n,t,1,0);
        add(t,i+n,0,0);
        
        int limit_y=0;
        for(int j=i-1; j>=1; j--)
        {
            if(po[j].y<limit_y||po[j].y>po[i].y) continue;
            limit_y=po[j].y;
            add(j+n,i,inf,0);
            add(i,j+n,0,0);
        }
    }
    add(s1,s2,2,0);
    add(s2,s1,0,0);
    printf("%d\n",maxcost_maxflow());
    return 0;
}

 

One is the cost side , one is to undertake the edge .

  Note: Now edge capacity between the two points should be inf, because this edge is actually connected to the upper right corner of the rectangle and the lower left corner, I saw a long time only to find why 90 ......

  The number of such edges would be greatly reduced, we can run spfa up!

  Code:

 

Guess you like

Origin www.cnblogs.com/popo-black-cat/p/10992894.html