这里会显示出您选择的修订版和当前版本之间的差别。
| 后一修订版 | 前一修订版 | ||
|
2020-2021:teams:legal_string:jxm2001:三元环计数 [2021/03/02 15:48] jxm2001 创建 |
2020-2021:teams:legal_string:jxm2001:三元环计数 [2021/05/26 14:16] (当前版本) jxm2001 |
||
|---|---|---|---|
| 行 9: | 行 9: | ||
| === 题意 === | === 题意 === | ||
| - | 给定 $n$ 个点和 $m$ 条边的无向图。定义三元环为满足 $(u,v,w)$ 两两之间有连边的点对数,求图中的三元环数。 | + | 给定 $n$ 个点和 $m$ 条边的无向图。定义三元环为满足所有点两两之间有连边的三元组数,求图中的三元环数。 |
| === 题解 === | === 题解 === | ||
| 行 71: | 行 71: | ||
| </hidden> | </hidden> | ||
| + | ==== 例题二 ==== | ||
| + | |||
| + | [[http://acm.hdu.edu.cn/showproblem.php?pid=6184|HDU6184]] | ||
| + | |||
| + | === 题意 === | ||
| + | |||
| + | 给定 $n$ 个点和 $m$ 条边的无向图。定义好的四元组 $(A,B,C,D)$ 为满足存在连边 $AB,BC,CD,DA,AC$ 的四元组,求图中好的四元组数。 | ||
| + | |||
| + | === 题解 === | ||
| + | |||
| + | 统计每条边出现在三元组中的次数 $c_i$,最终答案为 $\sum_{i=1}^n {c_i\choose 2}$ | ||
| + | |||
| + | <hidden 查看代码> | ||
| + | <code cpp> | ||
| + | const int MAXN=1e5+5,MAXM=2e5+5; | ||
| + | struct Edge{ | ||
| + | int to,next,c; | ||
| + | }edge[MAXM]; | ||
| + | int head[MAXN],edge_cnt; | ||
| + | void Insert(int u,int v){ | ||
| + | edge[++edge_cnt]=Edge{v,head[u],0}; | ||
| + | head[u]=edge_cnt; | ||
| + | } | ||
| + | int deg[MAXN],vis[MAXN],in[MAXN]; | ||
| + | pair<int,int> E[MAXM]; | ||
| + | int main() | ||
| + | { | ||
| + | int n,m; | ||
| + | while(cin>>n>>m){ | ||
| + | _rep(i,1,n)head[i]=deg[i]=vis[i]=in[i]=0; | ||
| + | edge_cnt=0; | ||
| + | _for(i,0,m){ | ||
| + | int u=read_int(),v=read_int(); | ||
| + | deg[u]++,deg[v]++; | ||
| + | E[i]=make_pair(u,v); | ||
| + | } | ||
| + | _for(i,0,m){ | ||
| + | int u=E[i].first,v=E[i].second; | ||
| + | if(deg[u]<deg[v]||(deg[u]==deg[v]&&u<v)) | ||
| + | Insert(u,v); | ||
| + | else | ||
| + | Insert(v,u); | ||
| + | } | ||
| + | _rep(u,1,n){ | ||
| + | for(int i=head[u];i;i=edge[i].next){ | ||
| + | int w=edge[i].to; | ||
| + | vis[w]=u,in[w]=i; | ||
| + | } | ||
| + | for(int i=head[u];i;i=edge[i].next){ | ||
| + | int v=edge[i].to; | ||
| + | for(int j=head[v];j;j=edge[j].next){ | ||
| + | int w=edge[j].to; | ||
| + | if(vis[w]==u) | ||
| + | edge[i].c++,edge[j].c++,edge[in[w]].c++; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | LL ans=0; | ||
| + | _rep(i,1,m) | ||
| + | ans+=1LL*edge[i].c*(edge[i].c-1)/2; | ||
| + | enter(ans); | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | </code> | ||
| + | </hidden> | ||