传递闭包——洛谷P2881 [USACO07MAR]排名的牛Ranking the Cows

来源:互联网 发布:淘宝模特要求 编辑:程序博客网 时间:2024/05/18 14:25

https://www.luogu.org/problem/show?pid=2881
传递闭包
可以floyd n*n*n
可以拓扑排序
zjoi省选讲过,可以用bitset优化;
然后我们的zhzh2001大作文章;
唉不说了;
大佬这样子;
老师这样子;
我们学生只能靠自己了;
题目意思就是要搞出一个表格
表示谁大于谁;
一单有未知,ans++;
显然答案最多是n*(n-1)/2;
就是每个两个就称一次;
比如n=100,我们最多答案就是4950;
其实用归并排序可以仅仅比较500~600次就好啦;
这个就很尴尬了;
folyd

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int N=1e3+5;bool f[N][N];int n,m,x,y,z,ans;int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++){        scanf("%d%d",&x,&y);        f[x][y]=1;    }    for(int k=1;k<=n;k++)        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)                if(f[i][k]&f[k][j])f[i][j]=1;    for(int i=1;i<=n;i++)if(f[i][i]){printf("-1");return 0;}    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)            if(!f[i][j]&&!f[j][i])ans++;    printf("%d",(ans-n)/2);}    

拓扑排序

#include<bits/stdc++.h>using namespace std;const int N=1e3+5;struct cs{int to,nxt;}a[N*10];int head[N],ll,g[N];bool f[N][N],vi[N],in[N];int n,m,x,y,z,ans;void init(int x,int y){    a[++ll].to=y;    a[ll].nxt=head[x];    head[x]=ll;}void bfs(){    queue<int>Q;    for(int i=1;i<=n;i++)if(!g[i])Q.push(i);    while(!Q.empty()){        int x=Q.front();Q.pop();vi[x]=1;        for(int k=head[x];k;k=a[k].nxt){            if(vi[a[k].to])exit(puts("-1")&0);            for(int i=1;i<=n;i++)if(f[i][x])f[i][a[k].to]=1;            g[a[k].to]--;            if(g[a[k].to]==0)Q.push(a[k].to);        }    }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)scanf("%d%d",&x,&y),init(x,y),f[x][y]=1,g[y]++;    bfs();    for(int i=1;i<=n;i++){        if(!vi[i])exit(printf("-1")&0);        for(int j=1;j<=n;j++)if(!f[i][j]&&!f[j][i])ans++;    }    printf("%d",(ans-n)/2);}

bitset(其实很简单的)

#include<bits/stdc++.h>using namespace std;const int N=1e3+5;struct cs{int to,nxt;}a[N*10];int head[N],ll,g[N];bool vi[N];bitset<N>f[N];int n,m,x,y,z,ans;void init(int x,int y){    a[++ll].to=y;    a[ll].nxt=head[x];    head[x]=ll;}void bfs(){    queue<int>Q;    for(int i=1;i<=n;i++)if(!g[i])Q.push(i);    while(!Q.empty()){        int x=Q.front();Q.pop();vi[x]=1;        for(int k=head[x];k;k=a[k].nxt){            if(vi[a[k].to])exit(puts("-1")&0);//            for(int i=1;i<=n;i++)if(f[i][x])f[i][a[k].to]=1;            f[a[k].to]=f[a[k].to]|f[x];            g[a[k].to]--;            if(g[a[k].to]==0)Q.push(a[k].to);        }    }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)scanf("%d%d",&x,&y),init(x,y),f[y][x]=1,g[y]++;    bfs();    for(int i=1;i<=n;i++){        if(!vi[i])exit(printf("-1")&0);    //    for(int j=1;j<=n;j++)if(!f[i][j]&&!f[j][i])ans++;        ans+=f[i].count();    }    printf("%d",n*(n-1)/2-ans);}
原创粉丝点击