sgu 196 Matrix Multiplication

39 篇文章 0 订阅
18 篇文章 0 订阅
196. Matrix Multiplication
time limit per test: 0.5 sec.
memory limit per test: 65536 KB
input: standard
output: standard



Let us consider an undirected graph G = <V, E> which has N vertices and M edges. Incidence matrix of this graph is an N × M matrix A = {aij}, such that aij is 1 if i-th vertex is one of the ends of j-th edge and 0 in the other case. Your task is to find the sum of all elements of the matrix ATA where AT is A transposed, i.e. an M × N matrix obtained from A by turning its columns to rows and vice versa.

Input

The first line of the input file contains two integer numbers — N and M (2 le N le 10,000, 1 le M le 100,000). 2M integer numbers follow, forming M pairs, each pair describes one edge of the graph. All edges are different and there are no loops (i.e. edge ends are distinct).

Output

Output the only number — the sum requested.

Sample test(s)

Input
4 4
1 2
1 3
2 3
2 4

Output

18


我们分析一下这个矩阵的乘法过程。

假设B=A'*A


那么B(i,j) = sum( A'(i,k) * A(k,j) ) (1<=k<=n)

we can know that A'(i,k) = A(k,i) = A(i,k)

so B(i,j) = sum( A(i,k) * A(j,k) )(1<=k<=n)

And the answer is sum ( B(i,j) )  (1<=i<=n,1<=j<=n)

 sum( B(i,j) ) = sum ( A(j,k) * sum( A(i,k) ) (1<=i,k,j<=n)

               = sum ( A(j,k) * deg(k) )   (1<=k,j<=n)

               = sum ( deg(k) * sum(j,k) ) (1<=k,j<=n)

               = sum ( deg(k) * deg(k) )(1<=k<=n)

( 汉英互切太蛋疼了,还好我还是会一些英语的。。。)

 我们可以很快预处理出所有的 deg(k)

 然后就可以很easy 算出答案了。

 我的程序中 两数组a , b 其实可以不用开,这样可以节省空间。


贴上代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<algorithm>
#include<vector>
#include<cstdlib>

#define inf 0xfffffff
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define FOR(a,b) for(int a=1;a<=(b);(a)++)

using namespace std;
int const nMax = 10100;
int const base = 10;
typedef int LL;
typedef pair<LL,LL> pij;

//    std::ios::sync_with_stdio(false);

int deg[nMax];
int n,m;
int a[nMax*10],b[10*nMax];  //可以改成 a,b的。节省空间

int main(){
    scanf("%d%d",&n,&m);
    FOR(i,m) {
        scanf("%d%d",&a[i],&b[i]);
        deg[a[i]]++;
        deg[b[i]]++;
    }
    long long ans=0;
    FOR(i,n) ans+=(deg[i]*deg[i]);
    printf("%I64d\n",ans);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值