Problem:
Score : 300 points

Problem Statement

There is a grid with H rows and W columns, where each square is painted black or white.

You are given H strings S_1, S_2, ..., S_H, each of length W.
If the square at the i-th row from the top and the j-th column from the left is painted black, the j-th character in the string S_i is #; if that square is painted white, the j-th character in the string S_i is ..

Find the number of pairs of a black square c_1 and a white square c_2 that satisfy the following condition:

There is a path from the square c_1 to the square c_2 where we repeatedly move to a vertically or horizontally adjacent square through an alternating sequence of black and white squares: black, white, black, white...

Constraints

1 \leq H, W \leq 400

|S_i| = W (1 \leq i \leq H)

For each i (1 \leq i \leq H), the string S_i consists of characters # and ..

Input

Input is given from Standard Input in the following format:

H W
S_1
S_2
:
S_H

Output

Print the answer.

Sample Input 1

3 3
.#.
..#
#..

Sample Output 1

10

Some of the pairs satisfying the condition are ((1, 2), (3, 3)) and ((3, 1), (3, 2)), where (i, j) denotes the square at the i-th row from the top and the j-th column from the left.

Sample Input 2

2 4
....
....

Sample Output 2

0

Sample Input 3

4 3
###
###
...
###

Sample Output 3

6

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)


#include <iostream>
using namespace std;
int H, W;
struct point{
    int color;
    int up;
};

int ans = 0;

point d[400][400];
struct color{
    int black;
    int white;
};

color num[160000];

struct action{
    int x;
    int y;
};

action act[4] = {{1,0},{0,1},{-1,0},{0,-1}};

int root(int i, int j){
    if(d[i][j].up == i*W + j){
        return d[i][j].up;
    }else{
        int x = d[i][j].up;
        d[i][j].up = root(x/W, x%W);
        return root(x/W, x%W);
    }
}

void unite(int p, int q, int r, int s){
    d[root(p,q)/W][root(p,q)%W].up = root(r,s);
}

int main(void) {
    // insert code here...
    cin >> H >> W;
    for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
            char a;
            cin >> a;
            if(a == '#'){
                d[i][j].color = 0;
            }
            if(a == '.'){
                d[i][j].color = 1;
            }
            d[i][j].up = i*W + j;
        }
    }
    
//    for(int i = 0; i < H; i++){
//        for(int j = 0; j < W; j++){
//            cout << d[i][j].color ;
//        }
//        cout << endl;
//    }
    for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
            
            if(d[i][j].color == 0){
                for(int a = 0; a < 4; a++){
                    if(d[i+act[a].x][j+act[a].y].color == 1 && i+act[a].x >= 0 && i+act[a].x < H && j+act[a].y >= 0 && j+act[a].y < W){
                        if(root(i,j) != root(i+act[a].x, j+act[a].y)){
                            unite(i,j, i+act[a].x,j+act[a].y);
                        }
                    }
                }
            }
            if(d[i][j].color == 1){
                for(int a = 0; a < 4; a++){
                    if(d[i+act[a].x][j+act[a].y].color == 0 && i+act[a].x >= 0 && i+act[a].x < H && j+act[a].y >= 0 && j+act[a].y < W){
                        if(root(i,j) != root(i+act[a].x, j+act[a].y)){
                            unite(i,j, i+act[a].x,j+act[a].y);
                        }
                    }
                }
            }
            
        }
    }
    
    for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
            if(d[i][j].color == 0){
                num[root(i,j)].black++;
            }
            if(d[i][j].color == 1){
                num[root(i,j)].white++;
            }
        }
    }
    
    for(int i = 0; i < H*W; i++){
        ans += num[i].black * num[i].white;
    }
    
    cout << ans << endl;
    
    
    return 0;
}