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;
}
}