传递闭包+例题

目录:

传递闭包:

定义:

求传递闭包的算法----Warshall算法:

代码:

例题:

例题一:【POJ-3660】


传递闭包:

定义:

在一个图中,如果i顶点到j顶点能够连通,j顶点到k顶点能够连通,那么i顶点到j顶点就能够连通,我们求出所有满足这种传递性的节点,计算完成后,我们也就知道任意两个节点是否相连。

求传递闭包的算法----Warshall算法:

其实就是floyd算法,没啥好讲的,直接上代码。

代码:

​
#include<algorithm>
#include<iostream>
#include<limits.h>
#include <sstream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#define mod 1000000007
#define MAXN 10001
typedef long long ll;
using namespace std;
int e[MAXN][MAXN];
int n,m;
int a,b;
void Warshall()
{
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
        {
            if(e[i][k])
            {
                for(int j=1;j<=n;j++)
                    if(e[k][j])
                        e[i][j]=1;
            }
        }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i=n;i++)
        for(int j=1;j<=n;j++)
            cin>>e[i][j];
    Warshall();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
            cout<<e[i][j];
        cout<<endl;
    }
}

​

例题:

例题一:【POJ-3660】

http://poj.org/problem?id=3660

题意:

n头牛参加比赛,给你m对关系(譬如给你a和b,那么给的就是a必赢b,当然,b能赢c,那么a也能赢c),问能确定多少头牛的排名。

思路:

先求出传递闭包,得到一个求完传递闭包后的邻接矩阵,然后对每头牛进行遍历,在遍历第i头牛时,我们对除了第i头牛之外的牛进行遍历,如果牛i能够与其它所有的牛决出胜负,就说明牛i能够确定排行,res++,只要牛i与其它任意一头牛不能够决出胜负,说明牛i不能够确定排名。

扫描二维码关注公众号,回复: 4471263 查看本文章

代码:

#include<algorithm>
#include<iostream>
#include<limits.h>
#include <sstream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#define mod 1000000007
#define MAXN 120
typedef long long ll;
using namespace std;
int n,m;
int a,b;
int e[MAXN][MAXN];
void GetB()//求传递闭包的函数
{
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
        {
            if(e[i][k])
            {
                for(int j=1;j<=n;j++)
                    if(e[k][j])
                        e[i][j]=1;
            }
        }
}
int main()
{
    cin>>n>>m;
    memset(e,0,sizeof(e));
    for(int i=1;i<=m;i++)
    {
        cin>>a>>b;
        e[a][b]=1;
    }
    GetB();
    int ans=0;
    int i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(i==j)
                continue;
            if(e[i][j]==0&&e[j][i]==0)//只要i牛与其它任意一个牛无法确定输赢,那么i牛就无法确定排行
                break ;
        }
        if(j>n)//如果这个条件满足,说明i牛与其它的所有牛都能够确定输赢,说明i牛能确定排行
            ans++;
    }
    cout<<ans<<endl;
}

猜你喜欢

转载自blog.csdn.net/qq_40938077/article/details/84964638