• 三元环 bitset入门


    题目:

    三元环

    (three.cpp/in/out 2s 256M)
    输入一个有向图的邻接矩阵,求有多少个三元环(A到B,B到C,C又回A)

    '+'表示从第i行指向第j列的有向图(表示i到j),'-'无任何意义
    Input
    第一行给出数字N,3<=N<=1500.接下来N行N列给出数字矩阵
    Output
    如题
    Sample Input
    4
    --+-
    +--+
    -+--
    --+-
    Sample Output
    2

    开两个bitset数组a[i]和b[i]。对于从i指向j的边,
    我们令a[i][j]=1,b[j][i]=1,表示i→j存在,j→i也存在,这样a[i]表示从i发出
    的终点的集合,b[i]表示到达i的边的起点的集
    合。然后枚举边,对于边i→j,只要将a[j]和
    b[i]并起来就是与这条边构成三元环的点集,
    统计这些点集中点的个数ans,因为每个三元
    环都要重复计算三遍,所以最后答案是ans/3

    a[i]即为从i发出的点的集合,b[j]即为j接收到的点的集合

    a[j]&b[i]表示中间的枚举点k,以i→k→j→i构成的三元环,这样的k会被我们枚举三遍因为i,j也可以为K,同理k也可为i,j

    图示如下:

    code:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 bitset<1510> a[1510],b[1510],p;
     4 char mp[1510][1510];
     5 int n;
     6 long long ans;
     7 int main()
     8 {
     9     scanf("%d",&n);
    10     for(int i=1;i<=n;i++)
    11         for(int j=1;j<=n;j++)
    12             cin>>mp[i][j];
    13     for(int i=1;i<=n;i++)
    14         for(int j=1;j<=n;j++)
    15             if(mp[i][j]=='+')
    16                 a[i][j]=b[j][i]=1;
    17     for(int i=1;i<=n;i++)
    18         for(int j=1;j<=n;j++)
    19             if(a[i][j])
    20             {
    21                 p=a[j]&b[i];
    22                 ans+=p.count();
    23             }
    24     printf("%lld
    ",ans/3);
    25     return 0;
    26 }
  • 相关阅读:
    安全和加密
    awk
    CentOS7练习
    CentOS7系统引导顺序以及排障
    网络配置
    RAID阵列搭建
    LVM逻辑卷
    java-web——第九课 request
    java-web——第八课 JSTL的显示格式
    java-web——第七课 JSTL
  • 原文地址:https://www.cnblogs.com/nlyzl/p/11679691.html
Copyright © 2020-2023  润新知