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. docker学习笔记之把容器commit成镜像

    docker提供了两种镜像制作的方式,提高了使用的灵活性: 1.可以将更改后的容器提交,制作成镜像(这是接下来要说明的) 2.通过Dockerfile来制作镜像 下面通过一个例子来展示方法1. 本地有 ...

  2. Linxu-mysql5.7源码安装

    Mysql5.7 Linux安装教程 1系统约定安装文件下载目录:/data/softwareMysql目录安装位置:/usr/local/mysql数据库保存位置:/data/mysql日志保存位置 ...

  3. jdbc插入mysql时间差14个小时的解决方案

    在java中new Date()输出的时间是没错的,插入到mysql后少了14个小时,原因是新版jdbc驱动的时区设置问题. 在jdbc连接url最后加上serverTimezone=GMT%2B8即 ...

  4. Java EE javax.servlet.http中的HttpSession接口

    HttpSession接口 public interface HttpSession (https://docs.oracle.com/javaee/7/api/javax/servlet/http/ ...

  5. ETL测试或数据仓库测试入门

    概述 在我们学习ETL测试之前,先了解下business intelligence(即BI)和数据仓库. 什么是BI? BI(Business Intelligence)即商务智能,它是一套完整的解决 ...

  6. MVC4中去掉浏览器生成的无关代码方法

    通过增加Web.Config配置,如: <add key="vs:EnableBrowserLink" value="false"/>可以去掉MVC ...

  7. ThreadLocal的原理与使用

    前言 在java web项目中,经常会使用到单例对象,从服务器启动那一时刻就实例化全局对象.然后会对某些全局对象的属性进行修改之类的操作,但是我们知道项目一般都是部署到tomcat.Jboss之类的服 ...

  8. vue项目使用qrcodejs2生成二维码

    最近写项目遇到一个需求,根据后台给的地址生成二维码,在网上找了下,qrcodejs2使用还是比较多,试了下也能实现需求,就整理下使用方法,方便以后使用   1. 安装包 cnpm i qrcodejs ...

  9. ActiveMQ入门操作示例

    1. Queue 1.1 Producer 生产者:生产消息,发送端. 把jar包添加到工程中. 第一步:创建ConnectionFactory对象,需要指定服务端ip及端口号. 第二步:使用Conn ...

  10. 【异常】lockfile.AlreadyLocked: ~/airflow/airflow-scheduler.pid is already locked

    1 完整异常信息 File "/usr/bin/airflow", line 32, in <module> args.func(args) File "/u ...