码迷,mamicode.com
首页 > 其他好文 > 详细

传递闭包(例题POJ3660)

时间:2018-06-07 14:08:17      阅读:285      评论:0      收藏:0      [点我收藏+]

标签:++   end   bsp   解析   log   article   拓扑   之间   clu   

概念: 

传递一种关系,例如 a//b   b//c  则 a//c 

从已知的初始关系中  推出最后所有对象之间的关系

初始时把所有有关系的标记为1 即a[i][j] = 1

然后用Floyd 推出最后的结果  则有关系的两个对象被标记为1

void Floyd()
{
    for(int k=0; k<=n; ++k)
        for(int i=0; i<=n; ++i)
            for(int j=0; j<=n; ++j)
                a[i][j] = a[i][j] || (a[i][k] && a[k][j]);
}

例题:POJ3660

题意:

n个牛打架  初始已知m个打架结果 求最后能确定具体名次的牛 有几个

开始就以为是拓扑排序 然后一想。。并查集?

行吧。。。在最短路专题 就是最短路把。。。

当然这题拓排和并查集也能做  https://blog.csdn.net/u010372095/article/details/45201653   请看大佬博客。。。

解析:

用Floyd确定最后的关系后如果 一个牛打败了x个  被y个打败 且x+y == n-1 则 这个牛的名次则可以确定 想一下是不是呀

那么。。。贴代码了。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 110;
int a[maxn][maxn];
int n,m;
void Floyd()
{
    for(int k=1; k<=n; ++k)
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=n; ++j)
                a[i][j] = a[i][j] || (a[i][k] && a[k][j]);
}
int main()
{
    cin>> n >> m;
    mem(a,0);
    for(int i=0; i<m; ++i)
    {
        int u, v;
        cin>> u >> v;
        a[u][v] = 1;

    }
    Floyd();
    int res = 0;
    for(int i=1; i<=n; ++i)
    {
        int ans = 0;
        for(int j=1; j<=n; ++j)
        {
            if(a[i][j] || a[j][i])
                ans++;
        }
        if(ans == n-1)
            res++;
    }
    cout<< res <<endl;
    return 0;
}

 

传递闭包(例题POJ3660)

标签:++   end   bsp   解析   log   article   拓扑   之间   clu   

原文地址:https://www.cnblogs.com/WTSRUVF/p/9149510.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!