离散数学-传递闭包(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\n");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; }