思维题— Count the Sheep

时间:2020-04-01
本文章向大家介绍思维题— Count the Sheep,主要包括思维题— Count the Sheep使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

转自:https://blog.csdn.net/qq_34374664/article/details/57405987

题目:http://www.fjutacm.com/Problem.jsp?pid=2534

一,前引

做这道题的时候,傻乎乎的用链式前向星去存图,然后去遍历,最后因为太复杂了做不下去。( ˘•灬•˘ )

进而百度了一下这道题的解法,我对天,着实是秀这个解法,完全没想到。

二,思路

题意大概是就是求能构成 1->2->3->4  这种关系的羊的个数

① 注意有公羊和母羊之分,我们可以 +N, 错开储存。

② 每只公羊的朋友只有母羊,每只母羊的朋友只有公羊。

③ 其实我们既然储存了每只羊的朋友,我们可以只看第二点和第三点,第一点和第四点就包含在他们的朋友中了。

 如图所示:

2 的朋友有 5 1 4 3

3 的朋友有 7 4 8 2

从图中可以清楚的看出来 其中有 四个点 的线 的个数是 3*3

第一个 3 是 母羊2 的朋友个数减一(为毛减一呢,因为要扣除 3 这个点)

第二个 3 是 公羊3 的朋友个数减一(为毛减一呢,因为要扣除 2 这个点)

④ 所以我们就可以遍历所有 母羊,累加 (当前的母羊的朋友个数-1)*(母羊的朋友公羊的朋友个数-1),反过来累加公羊也可以。

⑤ 最后乘以 2 就是答案了,因为朋友是双向的

 三,代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<bitset>
#include<iostream>
#include <string.h>
#include<vector>
using namespace std;
vector<vector<int> >v(100000 * 2);
int main(void)
{
    int t; scanf("%d", &t);
    while (t--)
    {
        int n, m, k; scanf("%d%d%d", &n, &m, &k);
        for (int i = 1; i <= n + m; i++)
            v[i].clear();
        for (int i = 1; i <= k; i++)
        {
            int x, y; scanf("%d%d", &x, &y);
            v[x].push_back(y + n);  //公 -> 母
            v[y + n].push_back(x);  //母 -> 公
        }
        long long sum = 0;
        for (int i = 1; i <= n; i++)
        {
            int men = v[i].size() ;    // 第 i 只公羊的朋友个数
            for (int j = 0; j < v[i].size(); j++)
            {
                int femen = v[v[i][j]].size();  // 第 i 只母羊的朋友个数
                sum += (femen - 1)*(men-1);
            }
        }
        printf("%lld\n", sum * 2);
    }
    system("pause");
    return 0;
}

end !!!

=========== ========== ======= ======= ====== ===== ==== === == =

过洞庭  唐珙 明

西风吹老洞庭波,一夜湘君白发多。
醉后不知天在水,满船清梦压星河。

原文地址:https://www.cnblogs.com/asdfknjhu/p/12613617.html