196. Matrix Multiplication
time limit per test: 0.5 sec.
memory limit per test: 65536 KB
memory limit per test: 65536 KB
input: standard
output: 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
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;
}