[POJ 3660]Cow Contest[DFS]

题目链接:[POJ 3660]Cow Contest[DFS]

题意分析:

给出N头奶牛,和奶牛间的M个关系,每个关系描述为 a, b 代表a能力比b强,问:给出这M个关系,你能准确确定多少只奶牛的能力排名。

解题思路:

确定奶牛排名,那么,知道它前面有多少比它强,后面有多少比他弱,加起来的和如果等于 n - 1,那么这头奶牛的排名也就确定了。

个人感受:

首先脑袋中飞出了拓扑排序,然并卵。然后就想到了怎么确定排名,就想到了上面的解题思路了。dfs求的那一段花了不少时间,想着优化,结果证实还是一个个统计不会错。

网上还有floyd的做法,这里就不赘述了。也算是给题解添了其它版本XD。

具体代码如下:

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;

const int MAXN = 111;

vector<int> G[MAXN], V[MAXN];
int cnt1[MAXN], cnt2[MAXN]; // cnt1:有多少点比该点弱(包括本身) cnt2:有多少点比该点强(包括本身)
bool vis[MAXN];

int dfs1(int x)
{
    int ret = 1;
    if (vis[x]) return 0;
    vis[x] = 1;
    if (!G[x].size()) return 1;
    for (int i = 0; i < G[x].size(); ++i)
    {
        int to = G[x][i];
        ret += dfs1(to);
    }
    return ret;
}

int dfs2(int x)
{
    int ret = 1;
    if (vis[x]) return 0;
    vis[x] = 1;
    if (!V[x].size()) return 1;
    for (int i = 0; i < V[x].size(); ++i)
    {
        int to = V[x][i];
        ret += dfs2(to);
    }
    return ret;
}

int main()
{
    int n, m, a, b; scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) cnt1[i] = cnt2[i] = 1;
    while (m --)
    {
        scanf("%d%d", &a, &b);
        G[a].push_back(b);
        V[b].push_back(a);
    }
    for (int i = 1; i <= n; ++i)
    {
        memset(vis, 0, sizeof vis);
        cnt1[i] = dfs1(i);
    }
    for (int i = 1; i <= n; ++i)
    {
        memset(vis, 0, sizeof vis);
        cnt2[i] = dfs2(i);
    }
    
    int ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        //cout << i << ": " << cnt1[i] << ' ' << cnt2[i] << endl;
        if (cnt1[i] + cnt2[i] - 1 == n) // 因为包括本身,所以多统计了一次
            ++ans;
    }
    printf("%d\n", ans);
    return 0;
}



你可能感兴趣的:(DFS)