POJ3660传递闭包

貌似以后数学里会学到,不过还是先水一篇博客吧

传递闭包

传递闭包一般用来解决一类具有传递性的问题。

定义:在交际网络中,给定若干个元素和若干对二元关系,且这些关系具有传递性,通过这些传递性推导出尽量多的元素之间的关系的问题叫做传递闭包。

也就是用已知条件来推出其他所有的可知条件。数独应该就是使用了传递闭包的一个例子。再比如,A>BB>C,通过传递闭包,我们就可以得到A>C

将传递闭包问题转化为图论问题。

把元素变成一个点,有关系就连一条边。
最后用Floyd算法解决两点之间的联通关系。


题目大意:已知一些人的绝对实力关系,让你推出,最后有多少人的绝对实力排名是已知的。
这就是经典的Floyd传递闭包。

不多说了 看题目和代码:

/*
 * @Author: hesorchen
 * @Date: 2020-04-14 10:33:26
 * @LastEditTime: 2020-05-06 10:21:30
 * @Link: https://hesorchen.github.io/
 */

#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define endl '\n'
#define PI cos(-1)
#define PB push_back
#define ll long long
#define INF 0x3f3f3f3f
#define mod 1000000009
#define lowbit(abcd) (abcd & (-abcd))
#define fre                              \
    {                                    \
        freopen("in.txt", "r", stdin);   \
        freopen("out.txt", "w", stdout); \
    }

int mp[110][110];

int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= m; i++)
    {
        int u, v;
        cin >> u >> v;
        mp[u][v] = 1;  //1代表u>v
        mp[v][u] = -1; //-1代表u<v
    }
    for (int k = 1; k <= n; k++)
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                //传递闭包
                if (mp[i][k] == 1 && mp[k][j] == 1)
                {
                    mp[i][j] = mp[i][k];
                    mp[j][i] = -mp[i][k];
                }
                else if (mp[j][k] == -1 && mp[k][i] == -1)
                {
                    mp[i][j] = mp[k][i];
                    mp[j][i] = -mp[k][i];
                }

    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        int sum = 0;
        for (int j = 1; j <= n; j++)
            if (mp[i][j])
                sum++;
        if (sum == n - 1)
            ans++;
    }
    cout << ans << endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值