题目描述
输入
输出
示例输入
2
3 1
1 2
3 2
1 2
2 3
示例输出
21
完美网络要求每个结点的度数不小于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; }