Codeforces 1067B - Multihedgehog 暴力+圖 (Codeforces Round #518 (Div. 1))
阿新 • • 發佈:2018-11-13
CF: dfs and similar ?? *2000
題意:
題目定義了一種新的圖,這裡我們叫做 “k層樹”,解釋一下:
當k為1的時候,有一個點度數>=3,其餘的點的度數都是1;
當k>=2的時候,把 k-1層圖 看作一個結點度數為1的點,然後有一個結點(純正的度數為1的結點)連線>=3個這樣的結點;
現在給你一個這樣的圖,判斷是不是 k層圖;
輸入n為結點個數,然後是k,然後n-1行表示邊; (題目保證是一棵樹)
思路:
我們假設這個圖是k層圖,然後我們把他按照一定的方式遍歷,中途遇到不合法的情況退出,最後判斷是否為k層
遍歷方式:先把度數為1的結點找到,那麼它連線的一定是“1層圖”的中心點,然後刪去這些度數為1的點,然後把跟他相連的點存起來,在下一層中,就把這些點看作一個度數為1的結點,然後還要記錄當這些結點的葉子,得>=3;
複雜度 n*常數 吧;
#include<bits/stdc++.h> using namespace std; #define out fflush(stdout); #define fast ios::sync_with_stdio(0),cin.tie(0); #define FI first #define SE second typedef long long ll; typedef pair<ll,ll> P; const int maxn = 1e5 + 7; const int INF = 0x3f3f3f3f; const ll mod = 998244353; int n, k; set<int> st[maxn]; int cnt[maxn]; int d[maxn]; int main() { scanf("%d%d", &n, &k); if(n < 4) { printf("No"); return 0; } int u, v; for(int i = 1; i < n; ++i) { scanf("%d%d", &u, &v); st[u].insert(v); st[v].insert(u); d[u]++, d[v]++; } int num = 0; set<int> t; for(int i = 1; i <= n; ++i) { if(d[i] == 1) { int j = *st[i].begin(); t.insert(j); cnt[j]++; st[j].erase(st[j].find(i)); num++; } } int ans = 1; set<int> t_; while(t.size()) { if(t.size() == 1) { int j = *t.begin(); if(cnt[j] < 3) { printf("No"); return 0; } num++; break; } for(auto i : t) { if(cnt[i] < 3 || st[i].size() != 1) { printf("No"); return 0; } int j = *st[i].begin(); t_.insert(j); cnt[j]++; st[j].erase(st[j].find(i)); num++; } t.clear(); for(auto i : t_) { t.insert(i); } t_.clear(); ans++; } if(num != n) { printf("No"); return 0; } if(ans == k) printf("Yes"); else printf("No"); return 0; }