4200: [Noi2015] The little gardener and the old driver

Source: Internet
Author: User
Tags time limit
4200: [Noi2015] The little gardener and the old driverTime limit:20 Sec Memory limit:512 mbsec Special Judge
submit:139 solved:80
[Submit] [Status] [Discuss] DescriptionThe little gardener, Mr. S, is in charge of a field, and the field can be seen as a two-dimensional plane. There are nn wishing trees on the fields, numbered,..., n1,2,3,..., N, each tree can be regarded as a point on the plane, where the second tree (1≤I≤N1≤I≤N) is located in coordinates (XI,YI) (Xi,yi). The coordinates of any two trees are different. The old driver, Mr P, drove from the Origin point (0,0) (0,0) and carried out several rounds of action. Each round, Mr. P first selects any direction that satisfies the following conditions: left, right, top, top 45∘45∘, upper right, 45∘45∘ one of five directions. Moving in this direction can reach a tree that he has not yet wished for. When the selection is complete, Mr P moves straight in that direction and must reach the nearest tree that has not been made in that direction, wishing under the tree and continuing with the next round of action. If the direction of the condition is not met, the action is stopped. He would take the best strategy and make a wish under as many trees as possible. If the optimal strategy is not unique, you can choose either one. Unfortunately, the small gardener, Mr S, found that because of the soft soil in the field, the old driver, Mr P's car, would leave a rut mark on the field in each round of the journey, and a track print could be seen as a line segment with two trees (or origin and a tree) as the end point. After Mr P, there are many other wishing-makers who plan to drive to the field to make a wish, and those wishing to choose an optimal strategy action like Mr P. Mr. S believes that the rut of the direction (i.e. upper, upper left 45∘45∘, right upper 45∘45∘ three directions) is not very beautiful, in order to maintain the image of the field, he intends to rent some road rolling machine, in this group of wishing to tamp all "may leave the direction of the rut imprinted" ground. The ground that "may leave the rut of the non-left direction" should be a number of segments on the field, each of which is contained in the path of an optimal strategy. Each mill has a working mode that meets the following three conditions: starting at the origin or any tree. Can only be moved up, left upper 45∘45∘, right upper 45∘45∘ one of three directions, and can only change direction or stop under the tree. Can only go through the "may leave non-left direction rutting printing" of the ground, but the same piece of ground can be more than a rolling machine through. Now Mr P and Mr S are asking you a question: please give Mr. P indicates any one of the optimal routes. Please tell Mr S how many roller mills you need to rent at least. Input

The 1th line of the input file contains 1 positive integer n, which represents the number of wishing trees. Next n rows, the i+1 line contains 2 integer xi,yi, separated by a single space, representing the coordinates of the tree I wish tree. output file includes 3 rows. The 1th line of the output file outputs 1 integer m, which indicates how many trees the Mr P can make a wish for. The 2nd line of the output file outputs m integers, separated by a single space between adjacent integers, indicating which trees should be made to make a wish in sequence. The 3rd line of the output file outputs 1 integers, representing the minimum number of rolling mills the Mr S needs to hire. Sample Input 6
-1 1
1 1
-2 2
0 8
0 9
0 Sample Output 3
2 1 3
3

Explanation

The best route 2 can wish 3 times: (0,0) → (−1,1) → (−2,2) → (0,0) → (a) → (−1,1) → (−2,2) or (0,0) → (0,8) → (0,9) → (0,10) (0,0) → (0,8) → (0,9) → (0,10 )。 At least 3 rolling mills, the route is (0,0) → (0,0) → (a), (−1,1) → (−2,2) (−1,1) → (−2,2) and (0,0) → (0,8) → (0,9) → (0,10) (0,0) → (0,8) → (0,9) → (0,10). HINT


Source

[Submit] [Status] [Discuss]




DP + has the lowest flow in the upper and lower bounds, the details are very very much ..... For a whole morning ...

first, consider the first two questions, the driving direction of the old driver can only be increased to the ordinate, or left and right to open, so can be separated DP

definition G[i]: The first point, the point shifted by y less than Yi, the maximum value

so for each I, from the bottom up to I in the direction of only three, find out these three directions in the distance I nearest point, direct transfer on the line

definition F[i]: The first point, the maximum value from the left or right .

for F[i] transfer, first let all possible paths open to the current layer, that is, to handle all the g[i of the layer]

greedy to think, if you want from the same layer I open to J, assuming I on J left, then the best solution is I first open to the left end, and then slowly to the right

The reverse is also the same, so for each layer of the f[i], from left to right from right to left, respectively, with G[i] update once on the line

thus the transfer of g[i] is to consider simultaneously the points of the three directions in the f[i] and G[i]

finally check all the points of the f[i],g[i], you can come to the first question.

now to find the path, either take a legitimate end, each time to determine which category it belongs to (the same layer transfer or lower layer to get up)

then the previous point is enumerated directly in the conforming transfer set, then the search is continued, and the intermediate points are added when the same layer is transferred.

This solves the first two questions, for the third question, the modeling is as follows

reverse the DP once, as in the way of finding the path, processing all the edges that may become the shortest path, ignoring the same layer side

for bottom-to-top edge (i,j), from I to j a lower bound is 1, the upper bound is the edge of the INF

for all possible points on the shortest path, from S to the edge of an INF, it is to the edge of the T even one INF

That is, you can enter infinitely from this point, and infinity stops at this point

The least viable stream for that network is the answer to the third question.

How to find the minimum flow. Search on the internet for a long time, to determine the complexity of the low and good implementation of the template

the loop flow is constructed first, but the edge is not added (T,s,inf)

then run the Super Yuanhui maximum flow, add (T,s,inf), run the second Super Yuanhui maximum flow, this run out of the maximum flow is the original image of the minimum flow


Finally, there is a lot of detail in this topic.

Online to see someone realize, said the topic given each layer of points not more than 1k, so each layer of direct O (n^2) violence to find the way

and then say only the 7th point of T. In fact, the 7th point does not have a limit of 1k points per layer at all .

Therefore, when I deal with it, it is open a vis array, judging which points have not been added to the shortest set

This allows DP to be written in BFS mode, but cannot find random paths at the same time (because the points of the path may have been passed before the set is entered)


in short, the farm problem is all good trouble ....

#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue

> #include <algorithm> #include <cmath> #include <map> using namespace std;
const int MAXN = 5E4 + 50;
const int MAXM = 2E6 + 20;

const int INF = ~0u>>1; struct e{int to,cap,flow;

E () {} e (int to,int cap,int flow): To, Cap (CAP), flow (flow) {}}EDGS[MAXM]; struct p{int x, y;

P () {} p (int x,int y): x (x), Y (y) {}}POINT[MAXN];

struct data{int num,typ; data () {} data (int num,int typ): num (num), Typ (Typ) {}}; struct d2{int x, Y, D2 () {} d2 (int x,int y): x (x), Y (y) {} bool operator < (const D2 &b) Const {if (X < b.x
		) return 1;
		if (x > B.x) return 0;
	Return y < b.y;

}
}; int n,cur = 1,CNT,TP,S,T,S,T,SUM,ANS,A[MAXN],IN[MAXN],OUT[MAXN], cur[maxn],f[maxn],g[maxn],pos[maxn],road[maxn],l[
MAXN];

BOOL IN_ROAD[MAXN],VIS[MAXN][2],REACH[MAXN][2],TYP[MAXN];
Vector <int> V[MAXN],P[MAXN],G[MAXN];
Queue <int> Q; Queue <daTa> Q2;
Map <int,int> MA,MB,MC;

Map <d2,bool> EDGs; BOOL CMP (const int &AMP;X,CONST int &y) {return point[x].x < point[y].x;} void Add (int x,int y,int cap) {V[x].pus H_back (CNT);
	edgs[cnt++] = E (y,cap,0); V[y].push_back (CNT);
edgs[cnt++] = E (x,0,0);

} int Tree (const int &AMP;X,CONST int &y,const int &siz) {return x < y?y:siz-1-y;}
	int Getint () {Char ch = getchar (); int ret = 0,a = 1; while (Ch < ' 0 ' | |
		' 9 ' < CH) {if (ch = = '-') A =-1;
	ch = getchar ();
	} while (' 0 ' <= ch && ch <= ' 9 ') ret = ret*10 + ch-' 0 ', ch = getchar ();
return ret*a;
	} void Pre_work () {n = getint ();
		for (int i = 1; I <= n; i++) {int x = Getint (), y = Getint (); Point[i] = P (x, y);
	A[i] = y; } Point[++n] = P (0,0);
	Sort (A + 1,a + n + 1);
	for (int i = 2; I <= n; i++) if (a[i]! = A[i-1]) a[++cur] = A[i];
		for (int i = 1; I <= n; i++) {int pos = Lower_bound (A + 1,a + cur + 1,point[i].y)-A;
	P[pos].push_back (i);
}
}
void Dp () {ma[0] = n; mb[0] = n; mc[0] = n;
	Reach[n][0] = reach[n][1] = 1;
		for (int i = 2; I <= cur; i++) {int siz = p[i].size (); Sort (P[i].begin (), P[i].end (), CMP); for (int j = 0; J < Siz; J + +) {int now = p[i][j]; P o = Point[now];
			Pos[now] = j;
				if (Ma.count (o.x)) {int Pre = ma[o.x]; int w = max (F[pre],g[pre]);
				G[now] = max (g[now],w + 1); G[now].push_back (Pre);
			REACH[NOW][1] = 1;
				} if (Mb.count (O.X-O.Y)) {int Pre = MB[O.X-O.Y]; int w = max (F[pre],g[pre]);
				G[now] = max (g[now],w + 1); G[now].push_back (Pre);
			REACH[NOW][1] = 1;
				} if (Mc.count (o.x + o.y)) {int Pre = MC[O.X+O.Y]; int w = max (F[pre],g[pre]);
				G[now] = max (g[now],w + 1); G[now].push_back (Pre);
			REACH[NOW][1] = 1;
		}} int Max = Reach[p[i][0]][1]?g[p[i][0]]:-inf; 
			for (int j = 1; j < Siz; J + +) {int now = p[i][j];
			if (max! =-inf) F[now] = Max + 1,reach[now][0] = 1; if (reach[now][1]) Max = max (max + 1,g[now] + j);
		else if (Max! =-inf) ++max;
		} Max = Reach[p[i][siz-1]][1]?g[p[i][siz-1]]:-inf; 
			for (int j = siz-2; J >= 0; j--) {Int. now = P[i][j];
			if (max! =-inf) F[now] = Max (F[now],max + 1), reach[now][0] = 1;
			if (reach[now][1]) Max = max (max + 1,g[now] + siz-1-j);
		else if (Max! =-inf) ++max; } for (int j = 0; J < Siz; J + +) {int now = p[i][j];
			P o = Point[now]; if (Reach[now][0] | | |
		REACH[NOW][1]) ma[o.x] = mb[o.x-o.y] = Mc[o.x+o.y] = now; }}}} void Push_road (int i,int k,int siz,int Y) {if (I < pos[k]) {for (int j = Pos[k]-1; j > i; j--) Ro
		AD[++TP] = P[y][j];
		for (int j = 0; J <= I; j + +) ROAD[++TP] = P[y][j];
	TYP[TP] = 1;
		} else {for (int j = pos[k] + 1; j < I; j + +) ROAD[++TP] = P[y][j];
		for (int j = siz-1; J >= i; j--) ROAD[++TP] = P[y][j];
	TYP[TP] = 1;
	}} void Dfs_road (int x,int typ) {ROAD[++TP] = x; if (Typ) {for (int i = 0; i < g[x].size (); i++) {int to = G[x][i];
			BOOL flag = 0,nex_typ;
			if (Reach[to][0] && f[to] + 1 = = G[x]) flag = 1,nex_typ = 0; 
			if (Reach[to][1] && g[to] + 1 = = G[x]) flag = 1,nex_typ = 1;
			if (flag) {dfs_road (To,nex_typ); return;
		}}}} else {int Y = Lower_bound (A + 1,a + cur + 1,point[x].y)-A,siz = P[y].size ();
				for (int i = 0; i < siz; i++) if (i! = Pos[x]) {int to = P[y][i];
					if (Reach[to][1] && g[to] + Tree (i,pos[x],siz) = = F[x]) {push_road (i,x,siz,y),--tp; Dfs_road (road[tp+1],1);
				Return }}}} void Build_graph () {for (int i = 1; I <= n; i++) {if (f[i] = = Ans) {vis[i][0] = 1;
			Q2.push (data (i,0));
		if (!TP) dfs_road (i,0); } if (g[i] = = Ans) {vis[i][1] = 1;
			Q2.push (data (i,1));
		if (!TP) dfs_road (i,1); }} while (! Q2.empty ()) {int k = Q2.front (). Num,typ = Q2.front (). Typ; Q2.pop ();
		In_road[k] = 1; if (Typ) {for (int i = 0; i < g[k].size (); i++) {int to= G[k][i];
				BOOL flag = 0;
				if (Reach[to][0] && f[to] + 1 = = G[k]) {if (!vis[to][0]) vis[to][0] = 1,q2.push (data (to,0)); flag = 1; } if (Reach[to][1] && g[to] + 1 = = G[k]) {if (!vis[to][1]) vis[to][1] = 1,q2.push (data (to,1)); FL 
				AG = 1; } if (flag &&!)
			Edgs.count (D2 (to,k))) ++in[k],++out[to],add (To,k,inf), EDGS[D2 (to,k)] = 1;
			}} else {int Y = Lower_bound (A + 1,a + cur + 1,point[k].y)-A;
			int siz = P[y].size ();
					for (int i = 0; i < siz; i++) if (i! = Pos[k]) {int to = P[y][i]; if (Reach[to][1] && g[to] + Tree (i,pos[k],siz) = = F[k]) {if (!vis[to][1]) vis[to][1] = 1,q2.push (Data (
					to,1)); }}}} for (int i = 1; I <= n; i++) if (In_road[i]) {ADD (s,i,inf);
			ADD (I,t,inf);
			int du = in[i]-out[i];
			if (Du > 0) Add (s,i,du), sum + = du;
		else if (Du < 0) Add (I,T,-DU);
	}} int Dfs (int x,int a) {if (x = = T) return A; int flow = 0; For (int &i = cur[x]; i < v[x].size (); i++) {E &e = edgs[v[x][i]]; if (E.cap = = E.flow | |
		L[E.TO]! = L[x] + 1) continue;
		int f = Dfs (E.to,min (A,e.cap-e.flow)); if (!f) continue; Flow + + F;
		E.flow + = f; Edgs[v[x][i]^1].flow-= f;
		A-= f; if (!
	A) return flow; } if (!flow) l[x] =-1;
return flow;
	} bool BFS () {for (int i = 1; I <= T; i++) l[i] = 0; L[s] = 1;
	Q.push (S); while (! Q.empty ()) {int k = Q.front ();
		Q.pop ();
			for (int i = 0; i < v[k].size (); i++) {e E = edgs[v[k][i]]; if (E.cap = = E.flow | |
			L[e.to]) continue; L[e.to] = l[k] + 1;
		Q.push (e.to);
}} return l[t];
	} int dinic () {int maxflow = 0;
		while (BFS ()) {for (int i = 1; I <= T; i++) cur[i] = 0;
	Maxflow + = Dfs (S,inf);
} return Maxflow; } int main () {pre_work ();
	Dp ();
	for (int i = 1; I <= n; i++) Ans = Max (Ans,max (f[i],g[i)); cout << Ans << Endl; s = n + 1; T = s + 1; S = t + 1;
	T = S + 1;
	Build_graph (); for (int i = tp-1; i > 1; i--) printf ("%d", road[i]);
	cout << road[1] << Endl; if (tp-1! = Ans) puts ("wrong answer!");
	Else puts ("Accepted"); Dinic (); ADD (T,s,inf);
	cout << dinic ();
return 0; }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.