Depth-first search of a few topics

The feeling is easier than moving some of the rules ...... But recently my mind a little paste.
The first is to note that there are two adjacent table, the figures in the sparse, edge information is preferably stored with each vertex Vector, instead of dense figures G [x] [y].
The second path is the minimum number of steps and the path memory ...... path or else will be copied to bestpath ...... chaos. I made a lot of times silly and then later debug. This error was stupid, but I started to have a clear thought.
Here are some specific issues.

One hundred practicing 2815 Castle problems
can basically be considered a template title of a connected graph. But there are several points. The first is how to count the number of the room? Anyway, I did not expect, the different rooms with different numbers staining. Statistics of the number of colors just fine. Then is to return to be visited on the outside dfs ...... or else have problems logically, I was the stupid.
Finally, AC codes:

//百练2815:城堡问题
#include <iostream>
#include <algorithm>
using namespace std;
const int maxm = 51;
int dx[] = {0, -1, 0, 1};
int dy[] = {-1, 0, 1, 0};
int visited[maxm][maxm];
int m, n;
int map[maxm][maxm];
int legal(int x, int y) {
	if (x < 0 || x >= m || y < 0 || y >= n) return 0;
	return 1;
}
int roomnum;
int maxroomsize;
int cursize;
int dfs(int x, int y) {
	++cursize;
	visited[x][y] = roomnum;
	for (int i = 0; i < 4; ++i) {
		if (!legal(x + dx[i], y + dy[i])) continue;
		if (visited[x + dx[i]][y + dy[i]]) continue;
		if (((map[x][y] >> i) & 1)) continue;
		visited[x + dx[i]][y + dy[i]] = roomnum;
		dfs(x + dx[i], y + dy[i]);
	}
	return 1;
}
int main() {
	cin >> m >> n;
	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < n; ++j) {
			cin >> map[i][j];
		}
	}
	int init = 1;
	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < n; ++j) {
			cursize = 0;
			if (visited[i][j]) continue;
			++roomnum;
			dfs(i, j);
			maxroomsize = max(maxroomsize, cursize);
		}
	}
	cout << roomnum << endl;
	cout << maxroomsize << endl;
	return 0;
}

Or below this:

//百练2815:城堡问题
#include <iostream>
#include <algorithm>
using namespace std;
const int maxm = 51;
int dx[] = {0, -1, 0, 1};
int dy[] = {-1, 0, 1, 0};
int visited[maxm][maxm];
int m, n;
int map[maxm][maxm];
int legal(int x, int y) {
	if (x < 0 || x >= m || y < 0 || y >= n) return 0;
	return 1;
}
int roomnum;
int maxroomsize;
int cursize;
int dfs(int x, int y, int & cursize) {
	//++cursize;
	visited[x][y] = roomnum;
	for (int i = 0; i < 4; ++i) {
		if (!legal(x + dx[i], y + dy[i])) continue;
		if (visited[x + dx[i]][y + dy[i]]) continue;
		if (((map[x][y] >> i) & 1)) continue;
		visited[x + dx[i]][y + dy[i]] = roomnum;
		cursize += 1;
		dfs(x + dx[i], y + dy[i], cursize);
	}
	maxroomsize = max(maxroomsize, cursize);
	return 1;
}
int main() {
	cin >> m >> n;
	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < n; ++j) {
			cin >> map[i][j];
		}
	}
	int init = 1;
	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < n; ++j) {
			//cursize = 0;
			if (visited[i][j]) continue;
			++roomnum;
			dfs(i, j, init);
			init = 1;
			//maxroomsize = max(maxroomsize, cursize);
		}
	}
	cout << roomnum << endl;
	cout << maxroomsize << endl;
	return 0;
}

One hundred practicing 1724 ROADS
I have actually looked courseware ideas ...... Okay. Cost storage is to take out the intermediate results as a dimension.
Note that this problem is more than one way, so use vector memory, can not be used adjacency matrix.
Also worth mentioning is that there is a pruning can lead to WA. If the next destination is not the N and take the road together we have spent some time equal to K pruning. This is wrong because there may be spending a route to 0.
There is, I try to do with the dynamic regulation, that is, "one for all", the state transition equation is:

minlength[roadinfo[i][j].dest][cost] = min(minlength[roadinfo[i][j].dest][cost], minlength[i][k] + roadinfo[i][j].length)

But the fact is not enough. Since taking into account the existence of turning back, so the search order has become a problem, because now not possible to i = 1 to i = N the search.
Finally, AC codes:

#include <iostream>
#include <algorithm>
#include <bitset>
#include <cstring>
using namespace std;
const int MAXN = 102;
const int MAXK = 10002;
const int MAXR = 10002;
const int INF = (1 << 30);
int N, K, R;
struct road{
	int cost;
	int length;
};
vector <road> roadinfo[MAXN][MAXN];
//int roadinfo[MAXN][MAXN][2];
int minlength[MAXN][MAXK];
int output = INF;
int visited[MAXN];
int dfs(int location, int cost, int curlength) {
	if (location == N) {
		if (cost <= K) {
			minlength[N][cost] = min(minlength[N][cost], curlength);
			output = min(output, minlength[N][cost]);
			return 1;
		}
	}
	for (int i = 2; i <= N; ++i) {
		if (visited[i]) continue;
		for (int j = 0; j < roadinfo[location][i].size(); ++j) {
			if (roadinfo[location][i][j].cost + cost > K) continue;
			//else if (roadinfo[location][i][j].cost + cost == K && i != N) continue;
			else if (roadinfo[location][i][j].length + curlength >= minlength[i][cost + roadinfo[location][i][j].cost]) continue;
			else if (roadinfo[location][i][j].length + curlength >= output) continue;
			else {
				visited[i] = 1;
				minlength[i][cost + roadinfo[location][i][j].cost] = roadinfo[location][i][j].length + curlength;
				minlength[i][cost + roadinfo[location][i][j].cost] = min(minlength[i][cost + roadinfo[location][i][j].cost], 
					minlength[location][cost] + roadinfo[location][i][j].length);
				dfs(i, roadinfo[location][i][j].cost + cost, roadinfo[location][i][j].length + curlength);
				visited[i] = 0;
			}
		}
	}
	return 0;
}
int main() {
	int S, D;
	road input;
	cin >> K >> N >> R;
	//memset(minlength, 1, sizeof(minlength));
	for (int i = 0; i < R; ++i) {
		cin >> S >> D;
		cin >> input.length >> input.cost;
		roadinfo[S][D].push_back(input);
	}
	for (int i = 0; i < MAXN; ++i) {
		for (int j = 0; j < MAXK; ++j) {
			minlength[i][j] = INF;
		}
	}
	minlength[1][0] = 0;
	visited[1] = 1;
	dfs(1, 0, 0);
	cout << (output == INF? -1: output) << endl;
	return 0;
}

In fact, written a bit long-winded ......
one hundred practicing 1190 birthday cake
this is the example, the main revelation is pruning the feasibility of predictability. There are search order from largest to smallest, from the bottom up, to facilitate the feasibility pruning (this reminds me of clustering and dynamic regulation ...... bottom-up than top-down seems to be highly efficient? This should be drained a lot of possibility). Also this topic there are a lot of details to deal with the attention.
First, it is the surface area of the cake, including the top of all the layers exposed area and the side area and the front part of the bottom is equal to the direct bottom area. And be careful not to forget to add.
Also enumerated beginning from the maximum height and the bottom radius, is provided int, note that the truncation of the fractional portion, and then begins the enumeration thus to +1.
Finally, there is a place for improvement is the memory of the search.
The final AC codes (copy handouts (Wulian)):

#include <stdio.h>
#include <algorithm>
#include <math.h> 
const int MAXN = 10000, MAXM = 20;
int N, M;
int minv[MAXM+1];
int mina[MAXM+1];
int maxv[MAXM+1][30][30];
int minarea = 0xffffff;
int area;
int calmaxv(int curdepth, int r, int h) {
	if (maxv[curdepth][r][h] != 0) return maxv[curdepth][r][h];
	else {
		int v = 0;
		for (int i = 0; i < curdepth; ++i) {
			v += (r - i) * (r - i) * (h - i);
		}
		maxv[curdepth][r][h] = v;
		return v;
	}
}
int dfs(int curdepth, int remv, int maxr, int maxh) {
	if (remv < 0) return 0;
	//printf("%d %d %d %d %d\n", curdepth, remv, maxr, maxh, area); 
	if (curdepth == 0) {
		//printf("yeah\n");
		if (remv == 0) {
			minarea = std::min(area, minarea);
			return 1;
		}
		else return 0;
	}
	if (minv[curdepth-1] > remv) return 0;
	if (mina[curdepth-1] + area >= minarea) return 0;
	if (calmaxv(curdepth, maxr, maxh) < remv) return 2;
	//printf("escape return\n");
	for (int r = maxr; r >= curdepth; --r) {
		if (curdepth == M) area = r*r; //别忘了底面积 
		for (int h = maxh; h >= curdepth; --h) {
			area += 2 * r * h;
			int x = dfs(curdepth - 1, remv - r*r*h, r-1, h-1);
			if (x == 2){
				area -= 2 * r * h;
				break;
			}
			else area -= 2 * r * h;
		}
	}
	return 0;
}
int main() {
	scanf("%d%d", &N, &M);
	for (int i = 1; i <= M; ++i) {
		minv[i] = minv[i-1] + i*i*i;
		mina[i] = mina[i-1] + 2*i*i;
	}
	if (minv[M] > N) printf("0\n");
	else {
		int MAXR = sqrt(double(N-minv[M-1])/M) + 1;
		int MAXH = double(N-minv[M-1])/(M*M) + 1; //注意这里加一,因为直接舍掉了小数部分 
		//printf("%d %d\n", MAXR, MAXH);
		dfs(M, N, MAXR, MAXH);
		if (minarea == 0xffffff) printf("0\n");
		else printf("%d\n", minarea);
	}
	return 0;
}

Great route Piece of
fact, this is the birthday cake modification problems. The feasibility pruning (on the cake inside strongest pruning) I did not think, at the beginning of a seek death wish of o (n ^ 2) versions tried several times before to their senses this is actually their own stupidity ...... a bit like a heuristic function. I took the last strategy is to record all the roads inside the minimum cost of that, and then if you have any pathcost plus (N-depth) * mincost big to give it than optimal solution, although this proved heuristic function compared to cake inside quite tricky, but still very useful.
Finally, AC codes:

#include <stdio.h>
#include <bitset>
#include <algorithm>
using namespace std;
int minpath = 0xffffff;
bitset<16> vstd;
int N;
int minr = 0xffffff;
int route[16][16];
int dfs(int location, int path, int depth) {
	if (location == N-1) {
		if (depth != N-1) return 0;
		minpath = min(minpath, path);
		return 1;
	}
	vstd[location] = 1;
	if (path >= minpath) {
		vstd[location] = 0;
		return 0;
	}
	for (int i = 1; i < N; ++i) {
		if (vstd[i]) continue;
		if (depth != N-2 && i == N-1) continue;
		if (path + route[location][i] >= minpath) continue;
		if ((N-depth)*minr + path >= minpath) continue;
		dfs(i, path + route[location][i], depth + 1);
	}
	vstd[location] = 0;
	return 0;
}
int main() {
	scanf("%d", &N);
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < N; ++j) {
			scanf("%d", &route[i][j]);
			if (route[i][j] == 0) route[i][j] = 0xffffff; 
			if (minr > route[i][j]) minr = route[i][j];
		}
	}
	dfs(0, 0, 0);
	printf("%d\n", minpath);
	return 0;
}

(A had initially wanted to try a search and then failed, the fact that A did not understand the algorithm (Wulian), finished the free look)
to the right.

Guess you like

Origin blog.csdn.net/weixin_44288817/article/details/90904873