Zoj 2316 Matrix Multiplication(思路)

H - Matrix Multiplication

ZOJ - 2316

首先我先说明一下,如果我英语不是太渣的话那么题中说的矩阵是 n ∗ m n*m nm的矩阵。(我知道是 n ∗ n n*n nn的邻接矩阵)。但是我看题解矩阵 A A A都是 n ∗ n n*n nn的邻接矩阵

题意:

n ​ n​ n个顶点, m ​ m​ m个双向边,下面输入 m ​ m​ m个边,从而生成一个矩阵 A ​ A​ A,如果顶点 u ​ u​ u, v ​ v​ v之间有一条边,那么 A u   v ​ A_{u~v}​ Au v的值为1,否则为 0 ​ 0​ 0 。现在让你求 A T ∗ A ​ A^{T}*A​ ATA 所得的矩阵的元素和。

解法:

​ 首先因为边是双向的,所以 A T = A A^{T}=A AT=A ,故求 A ∗ A A*A AA的元素和即可。但很明显的是矩阵相乘肯定不行,时间复杂度太大。

​ 我们可以转化为另一个问题,路径长度为2的所有路径个数。

​ 可以用组合学的加法原理,因为所有路径长度为2的路径的中间节点是确定的,我们可以把问题转化为 1 1 1~ n n n 每个节点作为长度为2的路径的中间节点的路径条数之和,比如样例边 1 2 ,2 3,对应的所有路径有

2 1 2

1 2 1

1 2 3

3 2 1

3 2 3

2 3 2

​ 我们可以枚举每个顶点u,顶点u作为路径长度为2的中间节点的路径个数为:顶点 u u u的入度 ∗ * 顶点 u u u的出度, 又因为边是双边边,故每个顶点的入度等于出度。

​ 故我们求所有顶点 u u u的度数平方和即可。

#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const ll maxn=1e4+200;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll degree[maxn];
int main(){
    ll ans=0;
    int t,n,m,cas=0;
    scanf("%d",&t);
    while(t--){
        if(cas)
            puts("");
        cas=1;
        scanf("%d %d",&n,&m);
        mset(degree,0);
        for(int i=1;i<=m;++i){
            int u,v;
            scanf("%d %d",&u,&v);
            degree[u]+=1;
            degree[v]+=1;
        }
        ans=0ll;
        for(int i=1;i<=n;++i){
            ans+=degree[i]*degree[i];
        }
        cout<<ans<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值