列表

详情


NC24077. [USACO 2017 Feb S]Why Did the Cow Cross the Road III

描述

Why did the cow cross the road? Well, one reason is that Farmer John's farm simply has a lot of roads, making it impossible for his cows to travel around without crossing many of them.

FJ's farm is arranged as an N×N square grid of fields (2≤N≤100), Certain pairs of adjacent fields (e.g., north-south or east-west) are separated by roads, and a tall fence runs around the external perimeter of the entire grid, preventing cows from leaving the farm. Cows can move freely from any field to any other adjacent field (north, east, south, or west), although they prefer not to cross roads unless absolutely necessary.

There are K cows () on FJ's farm, each located in a different field. A pair of cows is said to be "distant" if, in order for one cow to visit the other, it is necessary to cross at least one road. Please help FJ count the number of distant pairs of cows.

输入描述

The first line of input contains N, K, and R. The next R lines describe R roads that exist between pairs of adjacent fields. Each line is of the form r c r′ c′ (integers in the range 1…N), indicating a road between the field in (row r, column c) and the adjacent field in (row r′, column c′). The final K lines indicate the locations of the K cows, each specified in terms of a row and column.

输出描述

Print the number of pairs of cows that are distant.

示例1

输入:

3 3 3
2 2 2 3
3 3 3 2
3 3 2 3
3 3
2 2
2 3

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 35ms, 内存消耗: 38752K, 提交时间: 2019-09-27 10:38:55

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=11000;
int a[maxn*maxn];
int col[maxn*maxn],color;
int n,k,r;
bool cut[maxn][maxn];
int ans;

int get_num(int x,int y)
{
    return (x-1)*n+y;//用下标取出每个点的编号
}

int dx[5]={0,0,1,-1};
int dy[5]={1,-1,0,0};

bool check(int x,int y)
{
    if(x>=1&&y>=1&&x<=n&&y<=n)return 1;
    return 0;
}

void bfs(int x,int y)
{
    color++;
    queue<int>q1,q2;
    q1.push(x);q2.push(y);
    while(!q1.empty())
    {
        int u=get_num(q1.front(),q2.front());
        col[u]=color;
        for(int i=0;i<4;i++)
        {
            int xx=q1.front()+dx[i];
            int yy=q2.front()+dy[i];
            int v=get_num(xx,yy);
            if(check(xx,yy)&&!cut[u][v]&&!cut[v][u]&&!col[v])//转移时用cut数组判断
            {
                q1.push(xx);q2.push(yy);
                col[v]=color;
            }
        }q1.pop();q2.pop();
    }
}

int main()
{
    scanf("%d%d%d",&n,&k,&r);
    for(int i=1;i<=r;i++)
    {
        int x1,y1,x2,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        int num1=get_num(x1,y1);
        int num2=get_num(x2,y2);
        cut[num1][num2]=cut[num2][num1]=1;
    }
    for(int i=1;i<=k;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        a[i]=get_num(x,y);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(!col[get_num(i,j)])
            {
                bfs(i,j);
            }
        }
    }
    for(int i=1;i<k;i++)
    {
        for(int j=i+1;j<=k;j++)
        {
            if(col[a[i]]!=col[a[j]])ans++;
        }
    }cout<<ans;

}

C++(clang++11) 解法, 执行用时: 5ms, 内存消耗: 376K, 提交时间: 2020-11-28 09:48:27

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=105;

int sum, num, answer;
int n, k, r, rr, c, r1, c1, ans[N*N];
bool cow[N][N], ltk[N][N], a[N][N][4];
int stepx[4]={0, 1, 0, -1};
int stepy[4]={1, 0, -1, 0};

void dfs(int x, int y){
	//printf("%d %d\n", x, y);
	if(ltk[x][y]||x<1||x>n||y<1||y>n) return ;
	if(cow[x][y])++sum;
	ltk[x][y]=true;
	for (int i=0;i<4;++i){
		if(a[x][y][i]) continue;
		int xx=x+stepx[i];
		int yy=y+stepy[i];
		if(!ltk[xx][yy]) dfs(xx, yy);
	}
}

int main (){
	scanf ("%d%d%d", &n, &k, &rr);
	for (int i=1;i<=rr;++i){
		scanf ("%d%d%d%d", &r, &c, &r1, &c1);
		if(r==r1){
			a[r][min(c, c1)][0]=1;
			a[r][max(c, c1)][2]=1;
		}else{
			a[min(r, r1)][c][1]=1;
			a[max(r, r1)][c][3]=1;
		}
	}for(int i=1;i<=k;++i){
		scanf ("%d%d", &r, &c);
		cow[r][c]=true;
	}for(int i=1;i<=n;++i)
		for (int j=1;j<=n;++j)
			if(!ltk[i][j]){
				sum=0;
				dfs(i, j);
				if(sum)	ans[++num]=sum;
			}
	for (int i=1;i<num;++i)
		for (int j=i+1;j<=num;++j)
			answer+=ans[i]*ans[j];
	printf("%d\n", answer);
	
	return 0;
}

上一题