H - Matrix Multiplication
首先我先說明一下,如果我英語不是太渣的話那麼題中說的矩陣是的矩陣。(我知道是的鄰接矩陣)。但是我看題解矩陣都是的鄰接矩陣
題意:
個頂點,個雙向邊,下面輸入個邊,從而生成一個矩陣,如果頂點,之間有一條邊,那麼的值爲1,否則爲 。現在讓你求 所得的矩陣的元素和。
解法:
首先因爲邊是雙向的,所以 ,故求的元素和即可。但很明顯的是矩陣相乘肯定不行,時間複雜度太大。
我們可以轉化爲另一個問題,路徑長度爲2的所有路徑個數。
可以用組合學的加法原理,因爲所有路徑長度爲2的路徑的中間節點是確定的,我們可以把問題轉化爲~ 每個節點作爲長度爲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的中間節點的路徑個數爲:頂點的入度頂點的出度, 又因爲邊是雙邊邊,故每個頂點的入度等於出度。
故我們求所有頂點的度數平方和即可。
#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;
}