1001-degree
题目:
degree
Accepts: 1581Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 131072/131072 K (Java/Others)
思路:
设该简单图的联通块数(通过并查集计算出)为linkNum,最大度数的点的度数为mxDegree,那么答案就是(mxDegree+linkNum-1+k), 但由于该图没有圈,那么就是说明该图是树,而树的最大度数是n-1 (n为点数),所以答案不能大于n-1,那么 ans = min( mxDegree+linkNum-1+k ,n-1);
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 2e5+20; int pre[MAXN],degree[MAXN]; int vis[MAXN]; int find(int x){ if(pre[x]==x)return x; else{ return pre[x] = find(pre[x]); } } void join(int x,int y){ int fx = find(x); int fy = find(y); if(fx!=fy){ pre[fx] = fy; } } void init(int n){ memset(degree, 0, sizeof(degree)); memset(vis, 0, sizeof(vis)); for(int i=0;i<=n;i++){ pre[i] = i; } } int main() { int n, m, k,t; scanf("%d", &t); while(t--){ scanf("%d%d%d", &n, &m, &k); init(n); for(int i=1;i<=m;i++){ int a, b; scanf("%d%d", &a, &b); join(a, b); degree[a]++; degree[b]++; } /// 计算联通块数目 int linkNum = 0; for(int i=0;i<n;i++){ if(!vis[find(i)]){ linkNum++; vis[find(i)]=1; } } /// 找出最大度数 int mxDegree = 0; for(int i=0;i<n;i++){ mxDegree = max(mxDegree, degree[i]); } int ans = (mxDegree+linkNum-1+k); if(ans>n-1) ans = n-1; ///树的最大度数是 n-1 printf("%d ", ans); } return 0; }