poj3660 Cow Contest(Floyd-Warshall方法求有向图的传递闭包)

poj3660 Cow Contest(Floyd-Warshall方法求有向图的传递闭包)

poj3660

题意: 

有n头牛, 给你m对关系(a, b)表示牛a能打败牛b, 求在给出的这些关系下, 能确定多少牛的排名。

分析:

在这呢先说一下关系闭包:  

关系闭包有三种: 自反闭包(r), 对称闭包(s), 传递闭包(t)。

先画出 R 的关系图,再画出 r(R), s(R), t(R) 的关系图。

poj3660 Cow Contest(Floyd-Warshall方法求有向图的传递闭包)        poj3660 Cow Contest(Floyd-Warshall方法求有向图的传递闭包)       poj3660 Cow Contest(Floyd-Warshall方法求有向图的传递闭包)       poj3660 Cow Contest(Floyd-Warshall方法求有向图的传递闭包)

我们今天用的是传递闭包。   仅作为个人理解 传递闭包: 关系之间具有传递性(例如a> b, b> c, 那么a> c), 在那些已给出的关系基础上, 通过传递性, 把所有可能的关系都找出来。  如上图。

 

这里需要先求一下所有牛之间的传递闭包, 那么我们这题与传递闭包又有什么关系呢。 下面将慢慢解答。 

如果一头牛被x头牛打败,并且可以打败y头牛,如果x+y=n-1,则我们容易知道这头牛的排名就被确定了,所以我们只要将任一头牛,可以打败其他的牛的个数x, 和能打败该牛的牛的个数y求出来,在遍历所有牛判断一下是否满足x+y=n-1,就知道这个牛的排名是否能确定了(而传递闭包,正好将所有能得出关系都求出来了), 再将满足这个条件的牛数目加起来就是所求解。 x可以看成是入度, y是出度。

 

在floyd-warshall(不了解该算法的点这里)求每对顶点间的最短路径算法中,可以通过O(v^3)的方法求出图的传递闭包。可以位每条边赋以权值1,然后运行Floyd-Wareshall。如果从  i  到  j  存在一条路径,则d(i,j)<N,否则d(i,j)=MAX。

 

 一种改进的算法是:由于我们需要的只是判断是否从i到j存在一条通路,所以在Floyd-Wareshall中的动态规划比较中,我们可以把min和+操作改为逻辑or( ||  )和逻辑(&&)。也就是将  d[i][j] = min(d[i][j],  d[i][k]+dist[k][j]);    改成    if(d[i][j] == 1 || (d[i][k] == 1 && d[k][j] == 1))   d[i][j] = 1;

设  d(i,j) = 1表示从 i 到 j 存在一条通路 p,且 p 的所有中间节点都在0,1,2,…,k中, 否则d(i,j)=0。我们把边(i,j)加入到E*中当且仅当d(i,j)=1。

#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstring>
#include<vector>
using namespace std;

int n, m, ans, v[110][110];

void floyd()//求图的闭包, 把所有可以确定的关系都求出来
{
    for(int k = 1; k <= n; k++)
    {
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                if(v[i][j] == 1 || (v[i][k] == 1 && v[k][j] == 1))
                    v[i][j] = 1;
            }
        }
    }
}
int main()
{
    while(scanf("%d%d", &n, &m) != EOF)
    {
        memset(v, 0, sizeof(v));
        for(int i = 1; i <= m; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            v[x][y] = 1;
        }
        floyd();

        ans = 0;
        for(int i = 1; i <= n; i++)
        {
            int du = 0;
            for(int j = 1; j <= n; j++)//对于每头牛, 求是否有唯一排名
            {
                if(i == j) continue;
                if(v[i][j] == 1 || v[j][i] == 1)
                    du++;
            }
            if(du == n-1)
                ans++;
        }
        printf("%d\n", ans);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/wd-one/p/4545086.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109433.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • curl命令调试接口「建议收藏」

    一.场景再现大家好,很快就过年了,在这里先祝各位新年快乐,阖家欢乐!现在我们切入主题,在我们平时开发接口完成后,需要上线联调接口,而接口往往和业务逻辑精密联系,想要调试接口,就需要将业务测一遍,那么有没有更好的办法使得调试更简单?在这篇文章中,我将常用的接口分为两类:第一类:自己开发服务于自己系统的接口,该类接口调试可以在本地使用postman工具调试;第二类:不是自己开发,调用别人能力…

    2022年4月17日
  • 网络RJ45接口详解[通俗易懂]

    网络RJ45接口详解[通俗易懂]RJ45简介图1RJ45模块RJ45模块用于实现PHY之间的互连,包括PHY芯片经信号变压器与RJ45接口相连,如图1所示。RJ45连接器由插头和插座组成,RJ45插头又称水晶头,如图3-10所示。这两种元件组成的连接器连接于导线之间,以实现导线的电气连续性。RJ45连接器就是连接器中的最重要的一种插座。RJ45插座分屏蔽型和非屏蔽型两种。RJ是RegisteredJack的…

    2022年9月17日
  • futex机制介绍「建议收藏」

    futex机制介绍「建议收藏」1、概念futex:asortoffast,user-spacemutualexclusionprimitive. Futex是一种用户态和内核态混合的同步机制。首先,同步的进程间通过mmap共享一段内存,futex变量就位于这段共享的内存中且操作是原子的,当进程尝试进入互斥区或者退出互斥区的时候,先去查看共享内存中的futex变量,如果没有竞争发生,则只修改futex,而不用…

    2022年4月19日
  • 圆形目标中心点在tof相机坐标系下的三维坐标的计算(1)

    圆形目标中心点在tof相机坐标系下的三维坐标的计算(1)将tof相机得到的深度图像转换为灰度图像,然后对灰度图像进行双边滤波,去除噪声的同时使边缘得到较好的保持,然后对滤波后的灰度图像进行hough圆变换,得到圆心在图像中的像素坐标,然后利用tof相机的点云数据,求得圆心在tof相机坐标系下的三维坐标。程序如下:#include”opencv2/core/core.hpp”#include”opencv2/highgui/highgui.h

    2022年5月25日
  • 2000款商务通用PPT模板免费下载[通俗易懂]

    2000款商务通用PPT模板免费下载[通俗易懂]0001-大气黑金年终工作总结PPT模板.zip:https://baippt.ctfile.com/fs/5288276-3454633710002-简约大气工作总结PPT模板.zip:https://baippt.ctfile.com/fs/5288276-3454633380003-商务风职业规划PPT模板.zip:https://baippt.ctfile.com/fs/5288…

    2022年7月24日
  • jeesite快速开发平台(七)—-代码生成原理

    jeesite快速开发平台(七)—-代码生成原理

    2021年6月16日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号