Codeforces 653E (BFS set)

E. Bear and Forgotten Tree 2
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A tree is a connected undirected graph consisting of n vertices and n  -  1 edges. Vertices are numbered 1 through n.

Limak is a little polar bear. He once had a tree with n vertices but he lost it. He still remembers something about the lost tree though.

You are given m pairs of vertices (a1, b1), (a2, b2), ..., (am, bm). Limak remembers that for each i there was no edge between ai and bi. He also remembers that vertex 1 was incident to exactly k edges (its degree was equal to k).

Is it possible that Limak remembers everything correctly? Check whether there exists a tree satisfying the given conditions.

Input

The first line of the input contains three integers nm and k () — the number of vertices in Limak's tree, the number of forbidden pairs of vertices, and the degree of vertex 1, respectively.

The i-th of next m lines contains two distinct integers ai and bi (1 ≤ ai, bi ≤ n, ai ≠ bi) — the i-th pair that is forbidden. It's guaranteed that each pair of vertices will appear at most once in the input.

Output

Print "possible" (without quotes) if there exists at least one tree satisfying the given conditions. Otherwise, print "impossible" (without quotes).

Examples
input
5 4 2
1 2
2 3
4 2
4 1
output
possible
input
6 5 3
1 2
1 3
1 4
1 5
1 6
output
impossible
Note

In the first sample, there are n = 5 vertices. The degree of vertex 1 should be k = 2. All conditions are satisfied for a tree with edges 1 - 5,5 - 21 - 3 and 3 - 4.

In the second sample, Limak remembers that none of the following edges existed: 1 - 21 - 31 - 41 - 5 and 1 - 6. Hence, vertex 1couldn't be connected to any other vertex and it implies that there is no suitable tree.


题意:给定一个完全图删掉某些边剩下的边能否构成一个树,对节点1的度数有限制.

维护一个集合表示剩下的点,然后首先判断能够和1向连的点是否大于n-1-k;删除节点1,从剩下的节点中求

出所有的联通块,然后判断下是不是存在不能和1连边的联通块,如果不存在只需要判断联通块的个数是不

是小于k就好了

#include <bits/stdc++.h>
using namespace std;
#define maxn 3111111

int n, m, k;
set <int> p[maxn];
int q[maxn], tou, wei;
set <int> node;//剩下的点
set <int>::iterator it;
int del[maxn], cnt; //一次bfs中需要删除的点
vector <int> block[maxn];

void solve () {
    node.clear ();
    for (int i = 2; i <= n; i++)
        node.insert (i);
    tou = wei = 0;
    if (p[1].size () > n-1-k) {
        printf ("impossible\n");
        return ;
    }
    int block_cnt = 0;
    while (node.size () > 0) {
        block_cnt++;
        tou = wei = 0;
        q[wei++] = *node.begin(); node.erase (q[tou]);
        block[block_cnt].push_back (q[tou]);
        while (tou < wei) {
            int u = q[tou++]; cnt = 0;
            for (it = node.begin (); it != node.end (); it++) {
                int v = *it;
                if (!p[u].count (v)) {
                    del[cnt++] = v;
                    q[wei++] = v;
                    block[block_cnt].push_back (v);
                }
            }
            for (int i = 0; i < cnt; i++)
                node.erase (del[i]);
        }
    }
    int tot = 0;
    for (int i = 1; i <= block_cnt; i++) {
        bool flag = 0;
        for (int j = 0; j < block[i].size (); j++) {
            if (!p[1].count (block[i][j])) {
                tot++;
                flag = 1;
                break;
            }
        }
        if (!flag) {//联通块里所有的点都不能和1向连
            printf ("impossible\n");
            return ;
        }
    }
    printf ("%s\n", tot <= k ? "possible" : "impossible");
}

int main () {
    //freopen ("in.txt", "r", stdin);
    while (scanf ("%d%d%d", &n, &m, &k) == 3) {
        for (int i = 1; i <= n; i++) {
            p[i].clear ();
            block[i].clear ();
        }
        for (int i = 1; i <= m; i++) {
            int u, v;
            scanf ("%d%d", &u, &v);
            p[u].insert (v);
            p[v].insert (u);
        }
        solve ();
    }
    return 0;
}


你可能感兴趣的:(Codeforces 653E (BFS set))