[POJ 3660]Cow Contest[DFS]
2015-10-18 16:57
429 查看
题目链接:[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;
}
题意分析:
给出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;
}
相关文章推荐
- Understanding the Default DNS Application Directory Partitions in Active Directory
- 1769493476
- Libevent分析
- 条款37:绝不重新定义继承而来的 缺省参数值
- Java基础知识强化之网络编程笔记17:Android网络通信之 使用Http的Post方式读取网络数据(基于HTTP通信技术)
- 掌握的技能
- 软件工程师技术之路开始
- Jquery iframe获取父窗口中的元素
- memcached远程 telnet 无法连接,解决方案
- 条款36:绝对不要重新定义,继承而来的non-virtual函数
- BZOJ1037 生日聚会
- 剑指offer第二十一题【栈的压入、弹出序列】c++实现
- CSS一些小总结——个人向
- <LeetCode><Easy> 111 Minimum Depth of Binary Tree
- Memcached 服务器端命令
- 条款35:考虑virtual函数以外的其他选择
- Java基础知识强化之网络编程笔记16:Android网络通信之 使用Http的Get方式读取网络数据(基于HTTP通信技术)
- 企业微信公众平台订阅号运营11大技巧
- $().each() 与 $.each()解析
- STM32F4——内存管理