[bzoj]1930 pacman吃豆豆

Description

两个PACMAN吃豆豆。一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方。PACMAN走到豆豆处就会吃掉它。PACMAN行走的路线很奇怪,只能向右走或者向上走,他们行走的路线不可以相交。 请你帮这两个PACMAN计算一下,他们俩加起来最多能吃掉多少豆豆。

Input

第一行为一个整数N,表示豆豆的数目。 接下来 N 行,每行一对正整数,表示第i个豆豆的坐标。任意两个豆豆的坐标都不会重合。

Output

仅有一行包含一个整数,即两个PACMAN加起来最多能吃掉的豆豆数量

Sample Input

8

8 1

1 5

5 7

2 2

7 8

4 6

3 3

6 4

Sample Output

7

HINT

 

N < = 2000

Source

拼尽全力优化,最后还是超时1个点。。。

裸的费用流

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<queue>
  5 #include<algorithm>
  6 using namespace std;
  7 
  8 const int INF=0x7fffffff;
  9 
 10 struct Edge
 11 {
 12     int from,to,v,c,next;
 13 }E[6000000];
 14 int node=1;
 15 int head[5000],from[5000],dis[5000],vis[5000];
 16 
 17 int n,ans,S,T;
 18 struct point
 19 {
 20     int x,y;
 21 }P[2001];
 22 
 23 int read()
 24 {
 25     int x=0,f=1;char ch=getchar();
 26     while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
 27     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 28     return x*f;
 29 }
 30 
 31 void ins(int from,int to,int v,int c)
 32 {
 33     node++;
 34     E[node]=(Edge){from,to,v,c,head[from]};
 35     head[from]=node;
 36 }
 37 
 38 void insert(int from,int to,int v,int c)
 39 {
 40     ins(from,to,v,c);ins(to,from,0,-c);
 41 }
 42 
 43 bool spfa()
 44 {
 45     queue<int> Q;
 46     for(int i=0;i<=T;i++) dis[i]=-INF;
 47     Q.push(0);dis[0]=0;vis[0]=1;
 48     while(!Q.empty())
 49     {
 50         int q=Q.front();Q.pop();
 51         for(int i=head[q];i;i=E[i].next)
 52             if(E[i].v>0&&dis[q]+E[i].c>dis[E[i].to])
 53             {
 54                 dis[E[i].to]=dis[q]+E[i].c;
 55                 from[E[i].to]=i;
 56                 if(!vis[E[i].to])
 57                 {
 58                     Q.push(E[i].to);
 59                     vis[E[i].to]=1;
 60                 }
 61             }
 62         vis[q]=0;
 63     }
 64     return dis[T]!=-INF;
 65 }
 66 
 67 void mcf()
 68 {
 69     int x=INF;
 70     for(int i=from[T];i;i=from[E[i].from])
 71         x=min(E[i].v,x);
 72     for(int i=from[T];i;i=from[E[i].from])
 73     {
 74         ans+=x*E[i].c;
 75         E[i].v-=x;E[i^1].v+=x;
 76     }
 77 }
 78 
 79 bool cmp(point a,point b)
 80 {
 81     return a.x<b.x||(a.x==b.x&&a.y<b.y);
 82 }
 83 
 84 int main()
 85 {
 86     n=read();T=2*n+2;S=T-1;
 87     for(int i=1;i<=n;i++)
 88         P[i].x=read(),P[i].y=read();
 89     sort(P+1,P+n+1,cmp);
 90     insert(0,S,2,0);
 91     for(int i=1;i<=n;i++)
 92     {
 93         insert(S,i,1,0);
 94         insert(i,i+n,1,1);
 95         insert(i,i+n,1,0);
 96         insert(i+n,T,1,0);
 97     }
 98     for(int i=1;i<=n;i++)
 99     {
100         int inf=INF;
101         for(int j=i+1;j<=n;j++)
102         {
103             if(P[i].y<=P[j].y)
104             {
105                 if(P[j].y<inf)
106                     insert(i+n,j,2,0);
107                 inf=min(inf,P[j].y);
108             }
109         }
110     }
111     while(spfa())
112         mcf();
113     printf("%d",ans);
114     return 0;
115 }
原文地址:https://www.cnblogs.com/InWILL/p/6028007.html