• ACDream 1213 Matrix Multiplication (01矩阵处理)


    Matrix Multiplication

    Time Limit: 2000/1000MS (Java/Others) 
    Memory Limit: 128000/64000KB (Java/Others)

    Problem Description

          Let us consider undirected graph G = {V; E} which has N vertices and M edges. Incidence matrix of this graph is N × M matrix A = {ai,j}, such that ai,j 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.

    Input

          The first line of the input file contains two integer numbers — N and M (2 ≤ N ≤ 10 000, 1 ≤ M ≤100 000). Then 2*M 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 Input

    4 4
    1 2
    1 3
    2 3
    2 4

    Sample Output

    18

    Source

    Andrew Stankevich Contest 1
     
    题意:给出一个N个点个M条无向边的关系构成一个01矩阵,求01矩阵A*A^T后新矩阵的每个元素的值。
    分析:这个邻接矩阵的转置矩阵还是这个矩阵本身,那么题目就变成了求A^2,有1W个点的话,用普通的矩阵肯定存不下来的,会超内存。
    设原矩阵为A,矩阵相乘之后为B,转置之后矩阵还是本身,按照矩阵乘法本来是A的第 i 行乘第 j 列得到 Aij, 转变思路思考一下,可以变成第 Aij 可以变成每一行和该行本身相乘。
    可以先计算出每一列的1的个数用一维数组C存下来,然后如果Bij=1的话,就Bij*C[i],可以纸上模拟一下。
    换种说法,就是先存下每个点的度,然后把所有边的两边的点的度相加。
    数据可能会超int,用long long
    #pragma comprint(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<string>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<map>
    #include<stdlib.h>
    #include<time.h>
    #include<algorithm>
    #define LL __int64
    #define FIN freopen("in.txt","r",stdin)
    using namespace std;
    const int MAXN=10000+5;
    int cnt[MAXN];
    struct node
    {
        int x,y;
    }edge[100000+5];
    int main()
    {
        int n,m;
        while(scanf("%d %d",&n,&m)!=EOF)
        {
            memset(cnt,0,sizeof(cnt));
            for(int i=0;i<m;i++)
            {
                int u,v;
                scanf("%d %d",&u,&v);
                cnt[u]++;
                cnt[v]++;
                edge[i].x=u;
                edge[i].y=v;
            }
            long long ans=0;
            for(int i=0;i<m;i++)
            {
                int u=edge[i].x;
                int v=edge[i].y;
                ans+=cnt[u];
                ans+=cnt[v];
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    .NET面试题系列[2]
    .NET面试题系列[1]
    被淡忘的c#析构函数
    关于Spring IOC容器解释
    工作随笔记 点击除div自身之外的地方,关闭自己
    js获得控件位置
    PHP如何判断对象为空的方法分享
    PHP 网页调用本地exe程序实例
    PHP jQuery实现上传图片时预览图片的功能实例
    Yii 自带的分页实例
  • 原文地址:https://www.cnblogs.com/clliff/p/4761843.html
Copyright © 2020-2023  润新知