三元环 bitset入门

ぃ、小莉子 提交于 2019-12-01 10:14:33

题目:

三元环

(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\n",ans/3);
25     return 0;
26 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!