首页 > 其他分享 >NC106972 Cow Ski Area

NC106972 Cow Ski Area

时间:2023-07-26 12:00:11浏览次数:57  
标签:Cow Area int NC106972 add && include Ski id

NC106972 Cow Ski Area

一、题目

\(N*M\)的滑雪场,每个点都有他的高度,滑雪的时候只能向四周相邻的不高于当前点的高度的点滑,现在滑雪场准备修建若干个缆车线路,使得奶牛可以从任意一个点运动到滑雪场的每个点,问最少需要建多少条缆车线路。

二、题解

本质还是有向图,通过加边使其强连通。
相邻而且高度大于等于的关系建单向边,然后就是上一个题了—— \(tarjan\)缩点,统计入度和出度为零的点的个数。

\(Code\)

#include <stdio.h>
#include <iostream>
#include <map>
#include <algorithm>
#include <queue>
#include <string>
#include <cstring>
#include <vector>

// C++可以AC,G++直接挂掉
using namespace std;
const int MAXN = 550;                  // 原来矩阵的长宽最大值
const int N = MAXN * MAXN, M = N << 2; // 新建图的点个数,及边个数,此题的边比较多 普通的N<<1不够
int g[MAXN][MAXN];                     // 原始地势高低的矩阵

// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}

// Tarjan算法求强连通分量
int dfn[N], low[N], ts;
int stk[N], top;
int in_stk[N];
int id[N], scc_cnt;
int din[N], dout[N];
void tarjan(int u) {
    dfn[u] = low[u] = ++ts;
    stk[++top] = u;
    in_stk[u] = 1;
    for (int i = h[u]; ~i; i = ne[i]) {
        int v = e[i];
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        } else if (in_stk[v])
            low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]) {
        ++scc_cnt;
        int x;
        do {
            x = stk[top--];
            in_stk[x] = 0;
            id[x] = scc_cnt;
        } while (x != u);
    }
}

int n, m; // 行数与列数

int main() {
#ifndef ONLINE_JUDGE
    freopen("NC106972.in", "r", stdin);
#endif
    memset(h, -1, sizeof h); // 初始化链式前向星
    scanf("%d %d", &m, &n);  // 败家的东西,先输入m后输入n

    // 输入原始数据矩阵
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            scanf("%d", &g[i][j]);

    // 根据题意,向四边探索建图,建图用的点号计算办法(x-1)*m+y
    for (int x = 1; x <= n; x++)
        for (int y = 1; y <= m; y++) {
            int id = (x - 1) * m + y;
            if (x > 1 && g[x][y] >= g[x - 1][y]) add(id, id - m); // 上一行
            if (x < n && g[x][y] >= g[x + 1][y]) add(id, id + m); // 下一行
            if (y > 1 && g[x][y] >= g[x][y - 1]) add(id, id - 1); // 左一列
            if (y < m && g[x][y] >= g[x][y + 1]) add(id, id + 1); // 右一列
        }

    // 注意点的个数为n*m
    for (int i = 1; i <= n * m; i++)
        if (!dfn[i]) tarjan(i);

    // 遍历每条出边,看看此边的两个端点是不是在同一个连通分量中,如果不是,标识两个连通分量间的出度入度变化
    for (int u = 1; u <= n * m; u++) {
        for (int i = h[u]; ~i; i = ne[i]) {
            int v = e[i];
            int a = id[u], b = id[v];
            if (a != b)
                dout[a]++, din[b]++;
        }
    }
    // 统计所有连通分量入度、出度为零的个数
    // 将出度入度为零的强连通分量间建边,可以最少代价完成强连通补边
    int a = 0, b = 0;
    for (int i = 1; i <= scc_cnt; i++) {
        if (!din[i]) a++;
        if (!dout[i]) b++;
    }
    if (scc_cnt == 1) // 特判一个强连通分量的特殊情况
        printf("0\n");
    else
        printf("%d\n", max(a, b)); // 输出两者最大值
    return 0;
}

标签:Cow,Area,int,NC106972,add,&&,include,Ski,id
From: https://www.cnblogs.com/littlehb/p/17582121.html

相关文章

  • 题解 P4955 【[USACO14JAN]Cross Country Skiing S】
    postedon2021-02-2710:04:32|under题解|source这道题其实没有绿这么难,只需要二分+搜索就行了。读入。注意尽量不要用scanf读入bool,这好像是UB,可以用一个变量\(x\)存输入的数,然后直接类型转换。二分。套模版就行了,等一下我们再写\(\operatorname{check}()\)函......
  • skill
    skill向选定的进程发送信号冻结进程补充说明skill命令用于向选定的进程发送信号,冻结进程。这个命令初学者并不常用,深入之后牵涉到系统服务优化之后可能会用到。语法skill(选项)选项-f:快速模式;-i:交互模式,每一步操作都需要确认;-v:冗余模式;-w:激活模式;-V:显示版本号;-t:指定......
  • P8271 [USACO22OPEN] COW Operations S 奶牛操作
    P8271[USACO22OPEN]COWOperationsS奶牛操作目录P8271[USACO22OPEN]COWOperationsS奶牛操作[USACO22OPEN]COWOperationsS题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示分析code[P8271USACO22OPEN]COWOperationsS-洛谷|计算机科学教育新生态(......
  • PS眼睛糖果滤镜Alien Skin Eye Candy 7 for Mac v7.2.3.189汉化版
    AlienSkinEyeCandy是一款非常流行的Photoshop插件,它提供了许多专业级的效果和滤镜。软件下载:AlienSkinEyeCandy7中文版 以下是该插件的一些特色和推荐理由:丰富的效果和滤镜:AlienSkinEyeCandy提供了超过30种不同的效果和滤镜,包括金属、玻璃、木纹、水晶等等。这......
  • 题解 P4183 [USACO18JAN] Cow at Large P
    带有小trick的点分治。建议先做完弱化版再看。假如奶牛在\(u\),那么所需的最少农夫数为\(\sum\limits_{v\inson(u)}[dis(u,v)\geg_v][dis(u,fa_v)<g_{fa_v}]\)。其中\(dis(u,v)\)为\(u,v\)在树上的距离,\(g_u\)为\(u\)到离它最近的出入口的距离(BFS预处理),\(fa_u\)......
  • CodeForces 1848E Vika and Stone Skipping
    洛谷传送门CF传送门感觉比这场的F简单。发现我们要进行\(x\)不断乘一些数然后求答案的操作,猜测答案与\(x\)的因数有关。如果你对数字比较敏感,不难发现答案就是\(x\)的奇因子个数。官方题解的证明:设\(x=f+(f-1)+\cdots+(f-(c-1))\),由等差数列求和公......
  • Reading Skills
    HowtoreadquicklybuteffectivelyInacademiccontextsyouwillhavemuchtoread,fromthicktextbookstoacademicjournalarticles.Althoughthiscanseemoverwhelmingatfirst,youcanlearntocopebyusingvarious readingskills,aswellastrying......
  • Closest Cow Wins S 最近的奶牛获胜
    ClosestCowWinsS最近的奶牛获胜题目传送门目录ClosestCowWinsS最近的奶牛获胜题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示思路code题目描述FarmerJohn沿着一条高速公路拥有一个很长的农场,可以被看作类似于一维数轴。沿着农场有\(K\)块草地(\(1\le......
  • P3047 [USACO12FEB] Nearby Cows G
    #include<iostream>#include<vector>usingnamespacestd;constintN=100010,M=30;intn,m;intw[N];vector<int>g[N];intf[N][M],ans[N][M];voidDP1(intu,intfa){ for(inti=0;i<=m;i++)f[u][i]=w[u]; for(intx:g......
  • P3089 [USACO13NOV] Pogo-Cow S 弹簧踩高跷
    P3089[USACO13NOV]Pogo-CowS弹簧踩高跷洛谷题目传送门目录P3089[USACO13NOV]Pogo-CowS弹簧踩高跷题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示题目大意方法一(线段树维护dp)code方法二(单调队列维护dp)code题目描述Inanill-conceivedattempttoenhanc......