完美网络

题目描述

完美网络是连通网络的基础上要求去掉网络上任意一条线路,网络仍然是连通网络。求一个连通网络要至少增加多少条边可以成为完美网络。

输入

第一行输入一个数T代表测试数据个数(T<=20)。每个测试数据第一行2个数n,m 分别代表网络基站数和基站间线路数。基站的序号为从1到n。接下来m行两个数代表x,y 代表基站x,y间有一条线路。
(0 < n < m < 10000)

输出

对于每个样例输出最少增加多少线路可以成为完美网络。每行输出一个结果。

示例输入

2
3 1
1 2
3 2
1 2
2 3

示例输出

2

1

完美网络要求每个结点的度数不小于2。

#include <iostream> #include<cstdio> #include<cstdlib> #include<cstring>//memset函数在此头文件中; #include<queue> #include<algorithm>//sort函数在此头文件中; using namespace std; int degree[10001];//计入顶点的度数; int main() {     int t;     scanf("%d",&t);     while(t--)     {         priority_queue<int,vector<int>,greater<int> >q;//优先队列升序;顺序容器适配器         int sum=0;//统计应该添加的边数;         memset(degree,0,sizeof(degree));//元素度数的初始化;         int m,n;         scanf("%d%d",&n,&m);         while(m--)         {             int v1,v2;             scanf("%d%d",&v1,&v2);             degree[v1]++;             degree[v2]++;//度数         }         sort(degree+1,degree+n+1);//根据度数来节点升序排列;         for(int i=1;i<=n;i++)             if(degree[i]<2)//完美网络保证每个节点的度数大于等于二             q.push(degree[i]);         else//度数升序排列所以要跳出;             break;         while(q.size()>=2)//保证队列中有两个元素,才能互相加边         {             int a=q.top();             q.pop();             int b=q.top();             q.pop();             a++;             b++;             sum++;             if(a<2)//保证每个节点的度数大于等于二                 q.push(a);             if(b<2)//保证每个节点的度数大于等于二                 q.push(b);         }         if(!q.empty())//若队列中仅有一个元素,队列的长度为一时;             sum++;         printf("%d",sum);         if(t!=0)             printf("\n");     }     return 0; }

#include <cstdio>
#include <cstring>
#include <queue>
#include <functional>
#include <algorithm>
using namespace std;

int main(int argc, char const *argv[]) {
	int degree[10001], t, n, m, u, v;
	scanf("%d", &t);
	while(t--) {
		memset(degree, 0, sizeof(degree));
		scanf("%d %d", &n, &m);
		while(m--) {
			scanf("%d %d", &u, &v);
			degree[u]++;
			degree[v]++;
		}
		sort(degree+1, degree+1+n);
		priority_queue<int, vector<int>, greater<int> >q;
		for(int i=1; i<=n; ++i) {
			if(degree[i] < 2) q.push(degree[i]);	// 加入度小于 2 的点
			else break;
		}
		int cnt = 0;
		while(q.size() >= 2) {	// 每次取出两个点来连边
			int v1 = q.top();
			q.pop();
			int v2 = q.top();
			q.pop();
			v1++;
			v2++;
			cnt++;
			if(v1 < 2) q.push(v1);	// 度仍小于 2,放回队列
			if(v2 < 2) q.push(v2);
		}
		if(!q.empty()) cnt++;
		printf("%d\n", cnt);
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值