HDU - 6184 C - Counting Stars

  题目大意:有n个点,m条边,问有一共有多少个‘structure’也就是满足V=(A,B,C,D) and E=(AB,BC,CD,DA,AC)这样一个图形,类似于四边形中间连接了一条对角线。

  如果我们把这个四边形拆分的话,其实就是两个共用一条边的三角形,而在图中就是三元环。求三元环有两种求法,个人感觉这个三元环的时间复杂度很玄学。

  第一种一种就是枚举点x,然后枚举和点x相连的y,这时根据y的度,如果y的度小于等于sqrt(m),那么我们可以直接枚举和y相连的z,看z和x是否相连,这时时间复杂度最差是m*sqrt(m),如果y的度大于sqrt(m)的话,说明y有很多点相连,再枚举y的话就会超时,这时枚举再枚举x找z,根据set或者map来判断y和z是否相连,复杂度最差也是m*sqrt(m),详情见代码

 #include<cstdio>
#include<vector>
#include<set>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=;
set<ll> s;
vector<int> vv[N];
int link[N],book[N];
inline void init(int n)
{
s.clear();
for(int i=;i<=n;i++)
{
vv[i].clear();
link[i]=;
book[i]=;
}
}
int main()
{
int n,m,u,v;
while(~scanf("%d%d",&n,&m))
{
init(n);
for(int i=;i<m;i++)
{
scanf("%d%d",&u,&v);
vv[u].push_back(v);
vv[v].push_back(u);
s.insert(1ll*u*(n+)+v);//set保存u和v相连的信息
s.insert(1ll*v*(n+)+u);
}
ll ans=;
for(int x=;x<=n;x++)
{
book[x]=;//每个点只有枚举一遍
for(int i=;i<vv[x].size();i++)
link[vv[x][i]]=x;//记录和x点相连的点
//枚举和x相连的y
for(int i=;i<vv[x].size();i++)
{
int y=vv[x][i],sum=;
if(book[y])
continue;
if(1ll*vv[y].size()*vv[y].size()<=m)
{
//枚举找到和x相连的z
for(int j=;j<vv[y].size();j++)
if(link[vv[y][j]]==x)
sum++;
}
else
{
//枚举找到和y相连的z
for(int j=;j<vv[x].size();j++)
if(s.find(1ll*y*(n+)+vv[x][j])!=s.end())
sum++;
}
ans+=1ll*sum*(sum-)/;//每两个三元环就可以组成一个需要的图形
}
}
printf("%lld\n",ans);
}
return ;
}

暴力m*sqrt(m)

  当然上面那个做法有点类似于暴力,而且前向星建图会超时,不知道为啥子,所以我们还需要第二种方法

  第二种是枚举边,不过得先对边进行处理。也就是统计每个点的度,然后我们根据这个度把之前的双向边变成度数大的点指向度数小的点,度数相同按序号的有向边,这样构成了一个有向无环图。这样我们枚举每条边,统计这条边能构成几个三元环,最后统计答案。但时间复杂度我不懂算,很玄学,比第一种快了不只一倍,并且在建边时用swap会超时。。

 #include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=;
vector<pii> vv[N];
int link[N],line[N],du[N],val[*N],u[*N],v[*N];
inline void init(int n)
{
for(int i=;i<=n;i++)
{
du[i]=;
vv[i].clear();
link[i]=line[i]=;
}
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
init(n);
for(int i=;i<=m;i++)
{
val[i]=;
scanf("%d%d",&u[i],&v[i]);
du[u[i]]++,du[v[i]]++;
}
for(int i=;i<=m;i++)//按度数改成有向边
{//每条边记录下另一个端点和边的编号
if(du[u[i]]<du[v[i]])
vv[u[i]].push_back(pii(v[i],i));
else if(du[u[i]]>du[v[i]])
vv[v[i]].push_back(pii(u[i],i));
else
{
if(u[i]<v[i])
vv[u[i]].push_back(pii(v[i],i));
else
vv[v[i]].push_back(pii(u[i],i));
}
// 改成swap(u[i],v[i]),然后再建边会超时
}
for(int i=;i<=m;i++)//枚举每条边
{
int x=u[i],y=v[i];
for(int j=;j<vv[x].size();j++)
{//遍历和x相连的z
int z=vv[x][j].first,id=vv[x][j].second;
link[z]=x;//z和x相连
line[z]=id;//记录相连的这条边的编号
}
for(int j=;j<vv[y].size();j++)
{//遍历和y相连的z
int z=vv[y][j].first,id=vv[y][j].second;
if(link[z]==x)
{//如果这个z和x相连的话
val[i]++;
val[id]++;
val[line[z]]++;
//相关的三条边都可以组成了一个三元环
}
}
}
ll ans=;
for(int i=;i<=m;i++)
ans+=1ll*val[i]*(val[i]-)/;
printf("%lld\n",ans);
}
return ;
}

vector建图

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=;
struct Side{
int v,ne;
}S[*N];
int sn,head[N],link[N],line[N],du[N],val[*N],u[*N],v[*N];
inline void init(int n)
{
sn=;
for(int i=;i<=n;i++)
{
head[i]=-;
du[i]=;
link[i]=;
line[i]=-;
}
}
inline void add(int u,int v)
{
S[sn].v=v;
S[sn].ne=head[u];
head[u]=sn++;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
init(n);
for(int i=;i<m;i++)
{
val[i]=;
scanf("%d%d",&u[i],&v[i]);
du[u[i]]++,du[v[i]]++;
}
for(int i=;i<m;i++)
{
if(du[u[i]]<du[v[i]])
add(u[i],v[i]);
else if(du[u[i]]>du[v[i]])
add(v[i],u[i]);
else
{
if(u[i]<v[i])
add(u[i],v[i]);
else
add(v[i],u[i]);
}
}
for(int i=;i<m;i++)
{
int x=u[i],y=v[i];
for(int j=head[x];j!=-;j=S[j].ne)
{
link[S[j].v]=x;
line[S[j].v]=j;
}
for(int j=head[y];j!=-;j=S[j].ne)
{
int z=S[j].v;
if(link[z]==x)
{
val[i]++;
val[j]++;
val[line[z]]++;
}
}
}
ll ans=;
for(int i=;i<m;i++)
ans+=1ll*val[i]*(val[i]-)/;
printf("%lld\n",ans);
}
return ;
}

前向星建图

三元环HDU 6184的更多相关文章

  1. HDU 6184 Counting Stars 经典三元环计数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6184 题意: n个点m条边的无向图,问有多少个A-structure 其中A-structure满足V ...

  2. [hdu 6184 Counting Stars(三元环计数)

    hdu 6184 Counting Stars(三元环计数) 题意: 给一张n个点m条边的无向图,问有多少个\(A-structure\) 其中\(A-structure\)满足\(V=(A,B,C, ...

  3. hdu6184 Counting Stars 【三元环计数】

    题目链接 hdu6184 题解 题意是让我们找出所有的这样的图形: 我们只需要求出每条边分别在多少个三元环中,记为\(x\),再然后以该点为中心的图形数就是\({x \choose 2}\) 所以我们 ...

  4. Codeforces Gym 100342J Problem J. Triatrip 求三元环的数量 bitset

    Problem J. Triatrip Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/at ...

  5. Codeforces Gym 100342J Problem J. Triatrip 三元环

    题目链接: http://codeforces.com/gym/100342 题意: 求三元环的个数 题解: 用bitset分别统计每个点的出度的边和入度的边. 枚举每一条边(a,b),计算以b为出度 ...

  6. Codeforces Gym 100342J Problem J. Triatrip bitset 求三元环的数量

    Problem J. TriatripTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/att ...

  7. BZOJ 3498 PA2009 Cakes(三元环处理)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3498 [题目大意] N个点m条边,每个点有一个点权a. 对于任意一个三元环(j,j,k ...

  8. BZOJ3498PA2009 Cakes——三元环

    题目描述 N个点m条边,每个点有一个点权a.对于任意一个三元环(j,j,k)(i<j<k),它的贡献为max(ai,aj,ak) 求所有三元环的贡献和.N<100000,,m< ...

  9. Codechef SUMCUBE Sum of Cubes 组合、三元环计数

    传送门 好久没有做过图论题了-- 考虑\(k\)次方的组合意义,实际上,要求的所有方案中导出子图边数的\(k\)次方,等价于有顺序地选出其中\(k\)条边,计算它们在哪一些图中出现过,将所有方案计算出 ...

随机推荐

  1. redis 学习(20)-- 常见的持久化开发与运维问题

    常见的持久化开发与运维问题 fork 操作 fork 操作是一个同步操作,若执行较慢会阻塞 redis 主线程 执行时间与内存量相关:内存越大,耗时越长:虚拟机较慢,真机较快 查看 fork 执行时间 ...

  2. dev listbox使用

    private void Init() { List<Funcation> data = new List<Funcation>(); data.Add(new Funcati ...

  3. OSCP-Kioptrix2014-1 环境搭建

    环境搭建 该系列文章参考 : https://www.youtube.com/watch?v=bWM0BCQ5q1o&list=PL9WW-prbqvGzHsGK_OqTyYWbCZjucpI ...

  4. VS code自定义语法高亮

    语法高亮向导(Syntax Highlight Guide) (https://code.visualstudio.com/api/language-extensions/syntax-highlig ...

  5. 在线预览(pptx、ppt、pps、docx、doc、xlsx、xls)

    http://view.officeapps.live.com/op/view.aspx?src=<文档位置> 示例文档https://www.dujin.org/file/ppt/duj ...

  6. arm交叉编译sudo-1.8.6p7

    1.交叉编译 # tar -xvf sudo-1.8.6p7.tar.gz # cd sudo-1.8.6p7/ # mkdir build # ./configure --prefix=/home/ ...

  7. IPC之sem.c源码解读

    // SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/sem.c * Copyright (C) 1992 Krishna Balasubramania ...

  8. UDS报文解读

    UDS(Unified Diagnostic Services,统一的诊断服务)诊断协议是ISO 15765 和ISO 14229 定义的一种汽车通用诊断协议,位于OSI模型中的应用层,它可在不同的汽 ...

  9. qunee 流动的关系

    <!DOCTYPE html> <html> <head> <title>Hello Qunee for HTML5</title> < ...

  10. 天线basic

    1.实际应用时,按内置天线还是外置天线考虑. 内置时,净空区在 PCB 上所有层(all layer) 不能放置元件,走线和铺 GND  天线远离金属,至少要距离周围有较高的元器件 10 毫米以上: ...