思路:先不考虑1这个点,求有多少个连通块,每个连通块里有多少个点能和1连,这样就能确定1的度数的上下界。
求连通块用链表维护。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define ull unsigned long long using namespace std; const int N = 3e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const int Mod = 1e9 + 7; int n, m, k, tot, pre, cnt1, cnt2; bool vis[N], ok[N]; vector<int> ban[N]; struct node { int id, nx; } Link[N]; void add(int id) { Link[tot].id = id; Link[tot].nx = Link[0].nx; Link[0].nx = tot++; } int main() { Link[0].nx = -1; tot = 1; scanf("%d%d%d", &n, &m, &k); cnt1 = 0; for(int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); ban[u].push_back(v); ban[v].push_back(u); if(u == 1) ok[v] = true; if(v == 1) ok[u] = true; } for(int i = 2; i <= n; i++) add(i); int down = 0, up = 0; while(Link[0].nx != -1) { int cnt = 0; queue<int> que; que.push(Link[Link[0].nx].id); Link[0].nx = Link[Link[0].nx].nx; while(!que.empty()) { int u = que.front(); que.pop(); if(!ok[u]) cnt++; for(int b : ban[u]) vis[b] = true; pre = 0; for(int i = Link[0].nx; ~i; i = Link[i].nx) { int to = Link[i].id; if(!vis[to]) { que.push(to); Link[pre].nx = Link[i].nx; } else pre = i; } for(int b : ban[u]) vis[b] = false; } if(!cnt) { puts("impossible"); return 0; } down++; up += cnt; } if(k >= down && k <= up) puts("possible"); else puts("impossible"); return 0; } /* */