[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
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 }