UPC6352: Multiplayer Moo(dfs求连通块)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sxh759151483/article/details/81353977

The cows have come up with a creative new game, surprisingly giving it the least creative name possible: "Moo".
The game of Moo is played on an N×N grid of square cells, where a cow claims a grid cell by yelling "moo!" and writing her numeric ID number in the cell.

At the end of the game, every cell contains a number. At this point, a cow wins the game if she has created a region of connected cells as least as large as any other region. A "region" is defined as a group of cells all with the same ID number, where every cell in the region is directly adjacent to some other cell in the same region either above, below, left, or to the right (diagonals don't count).

Since it is a bit boring to play as individuals, the cows are also interested in pairing up to play as teams. A team of two cows can create a region as before, but now the cells in the region can belong to either of the two cows on the team.

Given the final state of the game board, please help the cows compute the number of cells belonging to the largest region that any one cow owns, and the number of cells belonging to the largest region that can be claimed by a two-cow team. A region claimed by a two-cow team only counts if it contains the ID numbers of both cows on the team, not just one of the cows.

输入

The first line of input contains N (1≤N≤250). The next N lines each contain N integers (each in the range 0…106), describing the final state of the game board. At least two distinct ID numbers will be present in the board.

输出

The first line of output should describe the largest region size claimed by any single cow, and the second line of output should describe the largest region size claimed by any team of two cows.

样例输入

4
2 3 9 3
4 9 9 1
9 9 1 7
2 1 1 9

样例输出

5
10

提示

In this example, the largest region for a single cow consists of five 9s. If cows with IDs 1 and 9 team up, they can form a region of size 10.

来源/分类

USACO 2018 US Open Contest, Silver 

第一问直接dfs求连通块,然后求得过程中记录出现过的数

第二问暴力选择两个数看作一个连通块再用dfs求连通块就可以

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
int n, Map[505][505], vis[505][505], sum, max1 = 0, max2 = 0;
int tx[4] = {0, 0, 1, -1};
int ty[4] = {1, -1, 0, 0}; 
struct node{
	int num, sum;
	node() {
		num = sum = 0;
	}
}a[maxn];

bool cmp(node x, node y) {
	return x.sum > y.sum;
}

void dfs(int x, int y, int num1, int num2) {
	for(int i = 0; i < 4; i++){
		int xx = x + tx[i];
		int yy = y + ty[i];
		if(xx > 0 && xx <= n && yy <= n && yy > 0 && !vis[xx][yy] && (Map[xx][yy] == num1 || Map[xx][yy] == num2)){
			vis[xx][yy] = 1;
			sum++;
			dfs(xx, yy, num1, num2);
		}
	}
}

int fff(int num1, int num2){
	int ans = 0;
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= n; j++) {
			if(!vis[i][j] && (Map[i][j] == num1 || Map[i][j] == num2)) {
				sum = 1;
				vis[i][j] = 1;
				dfs(i, j, num1, num2);
				ans = max(ans, sum);
			}
		}
	}
	return ans;
}


int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    	for(int j = 1; j <= n; j++)
    		scanf("%d", &Map[i][j]);
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= n; j++) {
			if(!vis[i][j]) {
				vis[i][j] = 1;
				sum = 1;
				dfs(i, j, Map[i][j], Map[i][j]);
				a[Map[i][j]].num = Map[i][j];
				a[Map[i][j]].sum += sum;
				max1 = max(max1, sum);
			}
		}
	}
	max2 = max1;
	sort(a, a + maxn, cmp);
	for(int i = 0; i < maxn; i++) {
		for(int j = i + 1; j < maxn; j++) {
			if(a[i].sum + a[j].sum <= max2)
				break;
			int t = fff(a[i].num, a[j].num);
			max2 = max(max2, t);
		}
	}
	printf("%d\n%d\n", max1, max2);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sxh759151483/article/details/81353977