离散数学-传递闭包(POJ3275)

就是n的元素给定m个关系求他们之间的关系。

eg.  ∵a>b and b>c ∴a>c

emmmm

若要知道n个元素的绝对关系,则需知道C(n,2)个关系。

例题:POJ3275

求法:Floyd。关系如下:

if(g[i][k] and g[k][j]) g[i][j]=1;

但是呢,对于这个题的数据范围O(n3)的解法是肯定不行的。

于是我们用链式前向星。

/*#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<vector>
using namespace std;
inline int read()
{
    int x=0,w=0;char c=getchar();
    while(!isdigit(c))w|=c=='-',c=getchar();
    while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return w?-x:x;
}
const int maxn=1e3+10;
int n,m;
bitset<maxn>g[maxn];


int main()
{
    n=read(),m=read();
    for(int i=1;i<=m;i++)
        g[read()][read()]=1;
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            if(g[i][k] & g[k][j])g[i][j]=1;
    for(int i=1;i<=n;i++) if(g[i][i]){
        printf("-1
");return 0;
    }
    int ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(!g[i][j] and !g[j][i])ans++;
    printf("%d",(ans-n)/2);
    return 0;
}*/
//上面是邻接矩阵

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define R register
using namespace std;
inline int read()
{
    int x=0,w=0;char c=getchar();
    while(!isdigit(c))w|=c=='-',c=getchar();
    while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return w?-x:x;
}
const int maxn=1100;
int head[2][maxn],to[2][maxn],nxt[2][maxn],ecnt,n,m;
inline void addedge(int from,int too)
{
    to[0][++ecnt]=too,nxt[0][ecnt]=head[0][from],head[0][from]=ecnt;
    to[1][ecnt]=from,nxt[1][ecnt]=head[1][too],head[1][too]=ecnt;
}
bool vis[maxn][maxn];
int main()
{
    n=read(),m=read();
    int ans=0;
    for(R int x,y,i=1;i<=m;i++)
    {
        x=read(),y=read();
        if(!vis[x][y])
            addedge(x,y),ans++,vis[x][y]=1;
    }
    for(R int u,v,k=1;k<=n;k++)
        for(R int i=head[1][k];i;i=nxt[1][i])
        {
            u=to[1][i];
            for(R int j=head[0][k];j;j=nxt[0][j])
            {
                v=to[0][j];
                if(vis[u][v])continue;
                vis[u][v]=1;
                ans++;
                addedge(u,v);
            }
        }
    printf("%d",n*(n-1)/2-ans);
    return 0;
}
原文地址:https://www.cnblogs.com/BrotherHood/p/13321744.html