完美网络

Think:
这道题我用了两种方法解答, 第一种就是 普遍的 利用优先队列来进行解答, 第二种 是看同学 写的 然后 学会的 用强连通图来进行解答;

思路(优先队列):
输入x y 对应度数 +1, 随后进行便利, 将度数小于2的放入队列中, 因为连通图的前提 必须是 每个节点的读书大于等于2。 全部完成后进行判断, 将队列的 队首两个元素出列 +1, 然后再一次判断是否满足 >2的条件。
最后判断队列是否全部出列。

思路(强连通图):
对于n个节点的强连通图,最多有n*(n-1)条边, 最少有(n*(n-1))/2条边。
计算节点的度数,如果节点度数小于等于1,则sum++,然后输出(sum+1)/2条需要的边数。

Problem Description
完美网络是连通网络的基础上要求去掉网络上任意一条线路,网络仍然是连通网络。求一个连通网络要至少增加多少条边可以成为完美网络。
Input
第一行输入一个数T代表测试数据个数(T<=20)。每个测试数据第一行2个数n,m 分别代表网络基站数和基站间线路数。基站的序号为从1到n。接下来m行两个数代表x,y 代表基站x,y间有一条线路。
(0 < n < m < 10000)
Output
对于每个样例输出最少增加多少线路可以成为完美网络。每行输出一个结果。
Example Input

2
3 1
1 2
3 2
1 2
2 3

Example Output

2
1

Author
中国海洋大学第三届“朗讯杯”编程比赛高级组试题

AC代码 (优先队列):

#include<bits/stdc++.h>
using namespace std;
int du[10086];
int main()
{
    int n, m;
    int T, i;
    cin >> T;
    while(T --)
    {
        cin >> n >> m;
        memset(du, 0, sizeof(du));
        int x, y;
        while(m --)
        {
            cin >> x >> y;
            du[x] ++;
            du[y] ++;
        }
        sort(du + 1, du + n + 1);
        priority_queue<int, vector<int>, greater<int> >s;

        for (i = 1; i <= n; i ++)
        {
            if (du[i] < 2)
                s.push(du[i]);
        }

        int a, b, cnt = 0;

        while(s.size() >= 2)
        {
            a = s.top();
            s.pop();
            b = s.top();
            s.pop();
            a ++;
            b ++;
            cnt ++;
            if (a < 2)
                s.push(a);
            if (b < 2)
                s.push(b);
        }
        if (!s.empty())
            cnt ++;

        cout << cnt << endl;
    }
}

AC代码(强连通图):

#include<bits/stdc++.h>
using namespace std;

int du[10086];

int main()
{
    int T, i;
    cin >> T;
    while(T --)
    {
        memset(du, 0, sizeof(du));
        int sum = 0;
        int n, m;
        int x, y;
        cin >>n >> m;
        while(m --)
        {
            cin >> x >> y;
            du[x] ++;
            du[y] ++;
        }

        for (i = 1; i <= n; i ++)
        {
            if (du[i] <= 1)
                sum ++;
        }

//        int cnt = sum * (sum - 1);

        cout << (sum + 1) / 2<< endl;

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值