洛谷 1道经典图论题目 题解

题目传送门

题目描述

The cows are having a picnic! Each of Farmer John's K (1 ≤ K ≤ 100) cows is grazing in one of N (1 ≤ N ≤ 1,000) pastures, conveniently numbered 1...N. The pastures are connected by M (1 ≤ M ≤ 10,000) one-way paths (no path connects a pasture to itself).

The cows want to gather in the same pasture for their picnic, but (because of the one-way paths) some cows may only be able to get to some pastures. Help the cows out by figuring out how many pastures are reachable by all cows, and hence are possible picnic locations.

K(1≤K≤100) 只奶牛分散在 N(1≤N≤1000)个牧场.现在她们要集中起来进餐。牧场之间有 M(1≤M≤10000) 条有向路连接,而且不存在起点和终点相同的有向路.她们进餐的地点必须是所有奶牛都可到达的地方。那么,有多少这样的牧场可供进食呢?

输入格式

Line 1: Three space-separated integers, respectively: K, N, and M

Lines 2..K+1: Line i+1 contains a single integer (1..N) which is the number of the pasture in which cow i is grazing.

Lines K+2..M+K+1: Each line contains two space-separated integers, respectively A and B (both 1..N and A != B), representing a one-way path from pasture A to pasture B.

输出格式

Line 1: The single integer that is the number of pastures that are reachable by all cows via the one-way paths.

输入输出样例

输入 #1

复制代码
2 4 4
2
3
1 2
1 4
2 3
3 4

输出 #1

复制代码
2

说明/提示

The cows can meet in pastures 3 or 4.

思路:

什么玩意儿啊?翻译都不给全!我作为啥也不懂的小学生,简直崩溃了!幸好我还有另一个刷题点(链接: 首页),里面有这道题的中文版(链接: 题目---母牛野餐)可以去看一下(没登陆的话下面有)以下是中文大意:

k(1≤k≤100)只奶牛分散在n(1≤n≤1000)个牧场。

现在它们要集中起来进餐。

牧场之间有m(1≤m≤10000)条有向路连接,而且不存在起点和终点相同的有向路。

它们进餐的地点(牧场)必须是所有奶牛都可到达的地方.那么,有多少这样的牧场呢?

第一行共三个整数k,n,m

接下来k行,每行一个整数表示一只奶牛所在的牧场编号

接下来m行,每行两个整数,表示一条有向路的起点和终点

所有奶牛都可到达的牧场个数

输入样例:

2 4 4
2
3
1 2
1 4
2 3
3 4

输出样例:

2

样例解释

牧场3,4是这样的牧场.

知道大意,就可以开始做题了!

俗话说的好,"图论背模板,数论背公式,高精背代码,动规背方程",我们首先定义一堆数组和变量(一个vector存储图),然后直接套DFS的模板!然后输入两下,直接DFS!最后统计有几个牧场可以到达的数量=总牧场的数量,然后输出就OK啦!

AC代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int num[1005],vis[1005],cnt[1005];
int k,n,m,ans;
vector<int>v[1005];
void DFS(int x)
{
    cnt[x]++;
    vis[x]=1;
    for(int i=0;i<v[x].size();i++)
    {
        if(!vis[v[x][i]])
        {
            DFS(v[x][i]);
        }
    }
}
int main()
{
    cin >> k >> n >> m;
    for(int i=1;i<=k;i++)
    {
        cin >> num[i];
    }
    for(int i=1;i<=m;i++)
    {
        int x,y;
        cin >> x >> y;
        v[x].push_back(y);
    }
    for(int i=1;i<=k;i++)
    {
        memset(vis,0,sizeof(vis));
        DFS(num[i]);
    }
    for(int i=1;i<=n;i++)
    {
        if(cnt[i]==k)
        {
            ans++;
        }
    }
    cout<<ans;
    return 0;
}

看到DFS函数里的东西,你是不是眼前一亮?对,这就是当年把我虐的****的图的深度优先遍历!

(其实广度优先遍历才是我最痛恨的,因为我做了3天才做出来!)所以,下一篇我们就来扒一扒这俩玩意儿

这篇博客就到这里啦,我们下篇博客再见!

相关推荐
励志成为嵌入式工程师2 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉2 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer2 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq2 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
wheeldown3 小时前
【数据结构】选择排序
数据结构·算法·排序算法
青花瓷4 小时前
C++__XCode工程中Debug版本库向Release版本库的切换
c++·xcode
观音山保我别报错4 小时前
C语言扫雷小游戏
c语言·开发语言·算法
幺零九零零5 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
TangKenny5 小时前
计算网络信号
java·算法·华为
景鹤5 小时前
【算法】递归+深搜:814.二叉树剪枝
算法