精华内容
下载资源
问答
  • 传递闭包

    2019-09-26 18:41:07
    传递闭包,就是把图中所有满足这样传递性的节点都弄出来,计算完成后,我们也就知道任意两个节点之间是否相连。 传递闭包的计算过程一般可以用Warshell算法描述: For每个节点iDo For每个节点jDo Ifj能到i...

    所谓传递性,可以这样理解:对于一个节点i,如果j能到i,i能到k,那么j就能到k。求传递闭包,就是把图中所有满足这样传递性的节点都弄出来,计算完成后,我们也就知道任意两个节点之间是否相连。 

    传递闭包的计算过程一般可以用Warshell算法描述: 
    For 每个节点i Do 
        For 每个节点j Do 
        If j能到i Then 
            For 每个节点k Do 
            a[j, k] := a[j, k] Or ( a[j, i] And a[ i, k] ) 
    其中a数组为布尔数组,用来描述两个节点是否相连,可以看做一个无权图的邻接矩阵。可以看到,算法过程跟Floyd很相似,三重循环,枚举每个中间节点。只不过传递闭包只需要求出两个节点是否相连,而不用求其间的最短路径长。

    转载于:https://www.cnblogs.com/FuTaimeng/p/5610355.html

    展开全文
  • c++求传递闭包

    2019-03-19 13:15:36
    传递闭包C++描述,应用c++语言描述传递闭包算法
  • 之前在题解里看到“传递闭包”,一直以为是一种很高级的算法,后来上离散数学的时候学到了,发现其实蛮简单的。从数学上来说,传递闭包是在集合 上求包含关系 的最小传递关系。从关系图的角度来说,就是如果原关系图...

    之前在题解里看到“传递闭包”,一直以为是一种很高级的算法,后来上离散数学的时候学到了,发现其实蛮简单的。

    从数学上来说,传递闭包是在集合

    上求包含关系
    的最小传递关系。从关系图的角度来说,就是如果原关系图上有
    路径,则其传递闭包的关系图上就应有从
    。通俗地讲,就是确定每个点是否能到达其他每个点

    而这,把Floyd最短路算法稍微改一下即可。设E是原来的关系矩阵,则可以这样写:

    for (int k = 1; k <= n; ++k)
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                if (E[i][k] && E[k][j])
                    E[i][j] = 1;
    

    就是依次判断:仅经由1号点能不能从i到达j,仅经由1、2号点能不能从i到达j……最后得到的E是传递闭包的关系矩阵。 E[i][j]如果等于1,则表示存在从ij的路径。时间复杂度是


    (POJ1975 Median Weight Bead)

    Description
    There are N beads which of the same shape and size, but with different weights. N is an odd number and the beads are labeled as 1, 2, ..., N. Your task is to find the bead whose weight is median (the ((N+1)/2)th among all beads). The following comparison has been performed on some pairs of beads:
    A scale is given to compare the weights of beads. We can determine which one is heavier than the other between two beads. As the result, we now know that some beads are heavier than others. We are going to remove some beads which cannot have the medium weight.
    For example, the following results show which bead is heavier after M comparisons where M=4 and N=5.
    1. Bead 2 is heavier than Bead 1.
    2. Bead 4 is heavier than Bead 3.
    3. Bead 5 is heavier than Bead 1.
    4. Bead 4 is heavier than Bead 2.
    From the above results, though we cannot determine exactly which is the median bead, we know that Bead 1 and Bead 4 can never have the median weight: Beads 2, 4, 5 are heavier than Bead 1, and Beads 1, 2, 3 are lighter than Bead 4. Therefore, we can remove these two beads.
    Write a program to count the number of beads which cannot have the median weight.Input
    The first line of the input file contains a single integer t (1 <= t <= 11), the number of test cases, followed by the input data for each test case. The input for each test case will be as follows:
    The first line of input data contains an integer N (1 <= N <= 99) denoting the number of beads, and M denoting the number of pairs of beads compared. In each of the next M lines, two numbers are given where the first bead is heavier than the second bead.Output
    There should be one line per test case. Print the number of beads which can never have the medium weight.Sample Input
    1
    5 4
    2 1
    4 3
    5 1
    4 2Sample Output
    2

    大意是给出一些水滴之间的的重量大小关系,求有多少滴水滴的重量不可能是这些水滴重量的中位数。(水滴的数量保证为奇数)

    这就可以建个图(设

    代表
    号水滴的重量,则
    有边代表
    )求传递闭包,对每个点都统计
    能到达多少个点、有多少个点能到达(相当于统计有多少水滴确定比它重、多少水滴确定比它轻)。如果这两个数中有一个大于n/2,那它就不可能成为中位数。
    #include <cstring>
    #include <iostream>
    using namespace std;
    bool E[105][105];
    int main()
    {
        ios::sync_with_stdio(false);
        int t;
        cin >> t;
        while (t--)
        {
            int n, m;
            cin >> n >> m;
            memset(E, 0, sizeof(E));
            for (int i = 0; i < m; ++i)
            {
                int x, y;
                cin >> x >> y;
                E[x][y] = 1;
            }
            for (int k = 1; k <= n; ++k)
                for (int i = 1; i <= n; ++i)
                    for (int j = 1; j <= n; ++j)
                        if (E[i][k] && E[k][j])
                            E[i][j] = 1;
            int cnt = 0;
            for (int i = 1; i <= n; ++i)
            {
                int from = 0, to = 0;
                for (int j = 1; j <= n; ++j)
                {
                    from += E[j][i];
                    to += E[i][j];
                }
                cnt += from > n / 2 || to > n / 2;
            }
            cout << cnt << endl;
        }
        return 0;
    }
    

    POJ3660 Cow Contest

    DescriptionN (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors.
    The contest is conducted in several head-to-head rounds, each between two cows. If cow A has a greater skill level than cow B (1 ≤ AN; 1 ≤ BN; AB), then cow A will always beat cow B.
    Farmer John is trying to rank the cows by skill level. Given a list the results of M (1 ≤ M ≤ 4,500) two-cow rounds, determine the number of cows whose ranks can be precisely determined from the results. It is guaranteed that the results of the rounds will not be contradictory.Input
    * Line 1: Two space-separated integers: N and M
    * Lines 2..M+1: Each line contains two space-separated integers that describe the competitors and results (the first integer, A, is the winner) of a single round of competition: A and BOutput
    * Line 1: A single integer representing the number of cows whose ranks can be determinedSample Input
    5 5
    4 3
    4 2
    3 2
    1 2
    2 5Sample Output
    2

    有若干只牛,给出它们之间的一些胜负关系,试求有多少只牛的排名无法确定。

    这个题我总感觉可以用并查集或拓扑排序之类的方法,但数据范围这么小,用传递闭包应该是最简单的了。求出传递闭包后,对于每个点,如果存在另一个点,既不能到达它也不能被它到达,说明这个点对应牛的排名是无法确定的。

    #include <iostream>
    using namespace std;
    bool E[105][105];
    int main()
    {
        ios::sync_with_stdio(false);
        int n, m;
        cin >> n >> m;
        for (int i = 0; i < m; ++i)
        {
            int x, y;
            cin >> x >> y;
            E[x][y] = 1;
        }
        for (int k = 1; k <= n; ++k)
            for (int i = 1; i <= n; ++i)
                for (int j = 1; j <= n; ++j)
                    if (E[i][k] && E[k][j])
                        E[i][j] = 1;
        int cnt = 0;
        for (int i = 1; i <= n; ++i)
        {
            bool ok = true;
            for (int j = 1; j <= n; ++j)
                if (i != j && !E[i][j] && !E[j][i])
                    ok = false;
            cnt += ok;
        }
        cout << cnt << endl;
        return 0;
    }
    

    Pecco:算法学习笔记(目录)zhuanlan.zhihu.com
    展开全文
  • 自反闭包 传递闭包Let’s take the following scenario: You have a ParentView with two child views, ChildView1 and ChildView2. On ChildView1, you have a button that should trigger an action in ChildView2...

    自反闭包 传递闭包

    Let’s take the following scenario: You have a ParentView with two child views, ChildView1 and ChildView2. On ChildView1, you have a button that should trigger an action in ChildView2.

    让我们采取以下情形:您有一个带两个子视图的ParentViewChildView1ChildView2 。 在ChildView1 ,您具有一个按钮,该按钮应触发ChildView2的操作。

    Now on that button tap, we want to change the text on that text field to something more appropriate. Let’s start by defining a typealias for our closure. If you don’t know what a closure is, it’s basically a method. You can read more about closures in the documentation.

    现在点击该按钮,我们想将该文本字段上的文本更改为更合适的文本。 让我们开始为闭包定义一个类型别名。 如果您不知道闭包是什么,那么它基本上就是一种方法。 您可以在文档中阅读有关闭包的更多信息。

    Let’s add the following typealias above our ParentView declaration:

    让我们在ParentView声明上方添加以下类型ParentView

    typealias OnClickHandler = (() -> Void)

    So it becomes:

    这样就变成了:

    typealias OnClickHandler = (() -> Void)
    struct ParentView: View {
    ...
    }

    And initialise it as an @State property in our ParentView:

    并将其初始化为我们的ParentView@State属性:

    struct ParentView: View {
    @State var onClick: OnClickHandler = { }
    ...}

    The idea here is that this onClick defined in the ParentView is our single source of truth. We don’t want another closure initialized somewhere along the call stack. We want this one passed to both our ChildViews.

    这里的想法是,这onClick中定义的ParentView是我们的单一数据源。 我们不希望在调用堆栈的某处初始化另一个闭包。 我们希望将此传递给两个ChildViews。

    In ChildView2, where our button is, we add it as an @Binding, as it’s already initialized in our ParentView and ChildView2 at this point only manipulates it. Then we add it as the action to our button:

    ChildView2 ,我们的按钮位于其中,我们将其添加为@Binding ,因为它已经在ParentViewChildView2进行了初始化,此时只能对其进行操作。 然后,将其作为操作添加到按钮中:

    You’ll notice that we deleted the old closure in which we would print our message and just passed ours as a parameter. This is not mandatory, but it’s shorter and cleaner.

    您会注意到,我们删除了旧的闭包,在该闭包中将打印消息,并将其作为参数传递给我们。 这不是强制性的,但更短,更干净。

    At this point, your ParentView is notifying you that you’re missing your onClick parameter when you’re initializing ChildView2, so let’s just add that:

    此时,您的ParentView会通知您在初始化ChildView2时缺少onClick参数,所以我们只需添加一下:

    You’ll notice we passed $onClick to ChildView2, as we defined our property as an @Binding, so we use $to pass the binding and not a value.

    您会注意到我们通过了$onClick ChildView2 ,因为我们将属性定义为@Binding ,所以我们使用$来传递绑定而不是值。

    We’re now going to do the same thing to our ChildView1 — add a binding property — but this time we’re also going to write the function that gets called when the button is tapped, and we’re going to assign that function to our passed closure:

    现在,我们将对ChildView1执行相同的ChildView1 -添加一个绑定属性-但这次我们还将编写在点击按钮时调用的函数,并将该函数分配给我们通过的关闭:

    The magic here is calling onAppear on the Text element. This means that when that field appears (think of viewDidAppear in UIKit), we are going to run the following code block. In that code block, we assign a function to our onClick closure that modifies the value of our string.

    这里的魔法呼唤onAppear 在Text元素上。 这意味着当该字段出现时(考虑UIKit中的viewDidAppear ),我们将运行以下代码块。 在该代码块中,我们为onClick闭包分配了一个函数,该函数可修改字符串的值。

    If you want to be fancy or your method is larger, you can even extract the whole code block into a different method and assign that to onClick:

    如果您想花哨或您的方法更大,您甚至可以将整个代码块提取到另一个方法中,并将其分配给onClick

    Now, through the magic of SwiftUI and Combine, you managed to link two views that have no knowledge of each other. Congratulations!

    现在,借助SwiftUI和Combine的魔力,您成功地链接了彼此不了解的两个视图。 恭喜你!

    奖金 (Bonus)

    “What if I want to do this with a view and UIViewRepresentable where I don’t have onAppear?”

    “如果我想有一个观点和UIViewRepresentable在那里我没有做到这一点onAppear ?”

    That’s a great question, Alex!

    这是一个很好的问题,Alex!

    In this case, we will use the function:

    在这种情况下,我们将使用以下函数:

    You can see that I’ve sent it to a background thread. This is because the compiler will notify us at runtime that “Modifying state during view update, this will cause undefined behavior.”

    您可以看到我已将其发送到后台线程。 这是因为编译器将在运行时通知我们“在视图更新期间修改状态,这将导致未定义的行为。”

    This is Apple’s way of saying that we’re updating a state while the view is being redrawn.

    这是Apple的一种说法,即在重绘视图时我们正在更新状态。

    And that’s it. The full code is available on GitHub. Happy coding!

    就是这样。 完整代码可在GitHub上获得 。 编码愉快!

    翻译自: https://medium.com/better-programming/passing-closures-between-swiftui-sibling-views-and-uiviewrepresentables-1f81a6cf5be6

    自反闭包 传递闭包

    展开全文
  • 离散数学-关系,集合,求自反闭包,对称闭包,传递闭包 离散数学-关系,集合,求自反闭包,对称闭包,传递闭包 离散数学-关系,集合,求自反闭包,对称闭包,传递闭包 离散数学-关系,集合,求自反闭包,对称闭包...
  • 之前在题解里看到“传递闭包”,一直以为是一种很高级的算法,后来上离散数学的时候学到了,发现其实蛮简单的。从数学上来说,传递闭包是在集合 上求包含关系 的最小传递关系。从关系图的角度来说,就是如果原关系图...

    之前在题解里看到“传递闭包”,一直以为是一种很高级的算法,后来上离散数学的时候学到了,发现其实蛮简单的。

    从数学上来说,传递闭包是在集合

    上求包含关系
    的最小传递关系。从关系图的角度来说,就是如果原关系图上有
    路径,则其传递闭包的关系图上就应有从
    。通俗地讲,就是确定每个点是否能到达其他每个点

    而这,把Floyd最短路算法稍微改一下即可。设E是原来的关系矩阵,则可以这样写:

    for (int k = 1; k <= n; ++k)
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                if (E[i][k] && E[k][j])
                    E[i][j] = 1;
    

    就是依次判断:仅经由1号点能不能从i到达j,仅经由1、2号点能不能从i到达j……最后得到的E是传递闭包的关系矩阵。 E[i][j]如果等于1,则表示存在从ij的路径。时间复杂度是


    (POJ1975 Median Weight Bead)

    Description
    There are N beads which of the same shape and size, but with different weights. N is an odd number and the beads are labeled as 1, 2, ..., N. Your task is to find the bead whose weight is median (the ((N+1)/2)th among all beads). The following comparison has been performed on some pairs of beads:
    A scale is given to compare the weights of beads. We can determine which one is heavier than the other between two beads. As the result, we now know that some beads are heavier than others. We are going to remove some beads which cannot have the medium weight.
    For example, the following results show which bead is heavier after M comparisons where M=4 and N=5.
    1. Bead 2 is heavier than Bead 1.
    2. Bead 4 is heavier than Bead 3.
    3. Bead 5 is heavier than Bead 1.
    4. Bead 4 is heavier than Bead 2.
    From the above results, though we cannot determine exactly which is the median bead, we know that Bead 1 and Bead 4 can never have the median weight: Beads 2, 4, 5 are heavier than Bead 1, and Beads 1, 2, 3 are lighter than Bead 4. Therefore, we can remove these two beads.
    Write a program to count the number of beads which cannot have the median weight.Input
    The first line of the input file contains a single integer t (1 <= t <= 11), the number of test cases, followed by the input data for each test case. The input for each test case will be as follows:
    The first line of input data contains an integer N (1 <= N <= 99) denoting the number of beads, and M denoting the number of pairs of beads compared. In each of the next M lines, two numbers are given where the first bead is heavier than the second bead.Output
    There should be one line per test case. Print the number of beads which can never have the medium weight.Sample Input
    1
    5 4
    2 1
    4 3
    5 1
    4 2Sample Output
    2

    大意是给出一些水滴之间的的重量大小关系,求有多少滴水滴的重量不可能是这些水滴重量的中位数。(水滴的数量保证为奇数)

    这就可以建个图(设

    代表
    号水滴的重量,则
    有边代表
    )求传递闭包,对每个点都统计
    能到达多少个点、有多少个点能到达(相当于统计有多少水滴确定比它重、多少水滴确定比它轻)。如果这两个数中有一个大于n/2,那它就不可能成为中位数。
    #include <cstring>
    #include <iostream>
    using namespace std;
    bool E[105][105];
    int main()
    {
        ios::sync_with_stdio(false);
        int t;
        cin >> t;
        while (t--)
        {
            int n, m;
            cin >> n >> m;
            memset(E, 0, sizeof(E));
            for (int i = 0; i < m; ++i)
            {
                int x, y;
                cin >> x >> y;
                E[x][y] = 1;
            }
            for (int k = 1; k <= n; ++k)
                for (int i = 1; i <= n; ++i)
                    for (int j = 1; j <= n; ++j)
                        if (E[i][k] && E[k][j])
                            E[i][j] = 1;
            int cnt = 0;
            for (int i = 1; i <= n; ++i)
            {
                int from = 0, to = 0;
                for (int j = 1; j <= n; ++j)
                {
                    from += E[j][i];
                    to += E[i][j];
                }
                cnt += from > n / 2 || to > n / 2;
            }
            cout << cnt << endl;
        }
        return 0;
    }
    

    POJ3660 Cow Contest

    DescriptionN (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors.
    The contest is conducted in several head-to-head rounds, each between two cows. If cow A has a greater skill level than cow B (1 ≤ AN; 1 ≤ BN; AB), then cow A will always beat cow B.
    Farmer John is trying to rank the cows by skill level. Given a list the results of M (1 ≤ M ≤ 4,500) two-cow rounds, determine the number of cows whose ranks can be precisely determined from the results. It is guaranteed that the results of the rounds will not be contradictory.Input
    * Line 1: Two space-separated integers: N and M
    * Lines 2..M+1: Each line contains two space-separated integers that describe the competitors and results (the first integer, A, is the winner) of a single round of competition: A and BOutput
    * Line 1: A single integer representing the number of cows whose ranks can be determinedSample Input
    5 5
    4 3
    4 2
    3 2
    1 2
    2 5Sample Output
    2

    有若干只牛,给出它们之间的一些胜负关系,试求有多少只牛的排名无法确定。

    这个题我总感觉可以用并查集或拓扑排序之类的方法,但数据范围这么小,用传递闭包应该是最简单的了。求出传递闭包后,对于每个点,如果存在另一个点,既不能到达它也不能被它到达,说明这个点对应牛的排名是无法确定的。

    #include <iostream>
    using namespace std;
    bool E[105][105];
    int main()
    {
        ios::sync_with_stdio(false);
        int n, m;
        cin >> n >> m;
        for (int i = 0; i < m; ++i)
        {
            int x, y;
            cin >> x >> y;
            E[x][y] = 1;
        }
        for (int k = 1; k <= n; ++k)
            for (int i = 1; i <= n; ++i)
                for (int j = 1; j <= n; ++j)
                    if (E[i][k] && E[k][j])
                        E[i][j] = 1;
        int cnt = 0;
        for (int i = 1; i <= n; ++i)
        {
            bool ok = true;
            for (int j = 1; j <= n; ++j)
                if (i != j && !E[i][j] && !E[j][i])
                    ok = false;
            cnt += ok;
        }
        cout << cnt << endl;
        return 0;
    }
    

    Pecco:算法学习笔记(目录)zhuanlan.zhihu.com
    展开全文
  • 题目描述 给定有限集合上二元关系的关系矩阵,利用传递闭包的定义式(不是warshall算法)求其传递闭包的关系矩阵。 源代码#include#define N 100int mult(int a[N][N],int b[N][N],int n,int c[N][N]){int i,j,k;for(i...
  • 一、关系闭包 、 二、自反闭包 、 三、对称闭包 、 四、传递闭包

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,589
精华内容 1,835
关键字:

传递闭包