博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P2419 [USACO08JAN]牛大赛Cow Contest
阅读量:7072 次
发布时间:2019-06-28

本文共 1518 字,大约阅读时间需要 5 分钟。

 

对于一个能够确定名次的点,可以注意到,对于该点,入度和出度的数量加起来等于N-1

(这样还是不够准确的
确切的说是,能够到达这个点的数量和这个点能够到达的数量的和

floyd不仅可以求两个点之间的最短路径,还能求两个点彼此是否能够相互到达

最后对于一个可以确定名次的点,能够到达的所有的点 加上 能够到达该点的所有点的和必须等于n-1
当然,我们可以通过二进制来简化这个过程

最后处理结果时,设一个变量flag, 因为该点能够到达本身,flag初值赋为1

对于两个点i, j首先f[i][j] | f[j][i]
因为对于这两个点,无论从j到i或是从i到j,都需算上。
同时用flag与f[i][j] | f[j][i]相&
按位与的操作是两位全为1,则得到的值为1,也就是说,若有任何一点不能到达此点或是由此点到达,我们就无法求出该点的名次
最后我们用计数器ans累加flag的值即可

1 #include
2 using namespace std; 3 const int maxn = 150; 4 int n, m, ans = 0; 5 int f[maxn][maxn]; 6 7 inline int read() { 8 int x = 0, y = 1; 9 char ch= getchar();10 while(!isdigit(ch)) {11 if(ch == '-') y = -1;12 ch = getchar();13 }14 while(isdigit(ch)) {15 x = (x << 1) + (x << 3) + ch - '0';16 ch = getchar();17 }18 return x * y;19 }20 21 int main() {22 n = read(), m = read();23 for(int i = 1; i <= m; ++i) {24 int x, y;25 x = read(), y = read();26 f[x][y] = 1;27 }28 for(int k = 1; k <= n; ++k)//floyd求两个点能否互相到达29 for(int i = 1; i <= n; ++i)30 for(int j = 1; j <= n; ++j)31 f[i][j] |= f[i][k] & f[k][j];32 for(int i = 1; i <= n; ++i) {33 int flag = 1;//判断i点是否能够求出具体的名次34 for(int j = 1; j <= n; ++j) {35 if(i == j) continue;36 else flag &= f[i][j] | f[j][i]; 37 }38 ans += flag;//统计答案39 }40 cout << ans << '\n';41 return 0; 42 }
View Code

 

转载于:https://www.cnblogs.com/ywjblog/p/9382164.html

你可能感兴趣的文章
模板方法模式
查看>>
一步一步实现一个简单的表单校验框架一
查看>>
查看手机号是否注册百度开发者
查看>>
前端工作流(draft)
查看>>
spring cloud eureka 高可用搭建
查看>>
OSChina 周二乱弹 —— 做羞羞事情的正确方法
查看>>
OSChina 周四乱弹 —— 会编程的女神长这样
查看>>
Coherence报socket错误
查看>>
面对、接受、处理、放下
查看>>
Eclipse自动生成jni头文件
查看>>
设计模式--外观模式
查看>>
mongodb_shard
查看>>
java成为移动互联网时代必学语言的六大理由
查看>>
git使用实践
查看>>
ABBYY FineReader 12的强大用途
查看>>
java实现KMP字符串匹配算法
查看>>
四种对象属性的复制
查看>>
springmvc-json小案例
查看>>
运行JAR文件(java -jar)
查看>>
解析Cloudera Manager内部结构、功能包括配置文件、目录位置等
查看>>