zoukankan      html  css  js  c++  java
  • 【Codeforces Round #694 (Div. 1) D】Strange Housing

    题目链接

    链接

    翻译

    让你在 (n) 个点上放老师,使得这 (n) 个点任意两个点之间都有路径。

    但是所给的路径要激活才能用,而激活的条件就是路径连接的两个点中,有一个点放了老师。

    当然一条路径不能两个端点都放老师,不然他们会打架 2333

    输出任意一个合法的方案即可。

    题解

    随便找一个没染色的点 (u),染成黑色。

    然后把所有和 (u) 相邻的点集 (V) 都染成白色。

    这样,保证了这些白色的点都有从 (u) 开始的路径可达。

    并且,这样做了之后,也能够保证这个黑色节点 (u) 不会有其他黑色节点和它相连。

    紧接着,我们再从刚刚染成白色的 (V) 中,找一个点 (v),然后对于和它相邻的未染色的节点 (x)

    (x) 看成是新的 (u'), 然后对这个新的 (u') 也染成黑色,之后同样地,将与 (u') 相邻的所有点都染成白色。

    重复上述步骤,直到所有的点都被染色了为止。

    这样操作一番之后,所有黑色的节点之间都仅隔着一个白色的点,所以可以互相到达。

    而每个黑色的节点周围都是白色,保证所有白色节点也可以到达。并且,黑色节点周围都是白色,不会有嘿嘿的冲突。

    perfect!

    实现的时候,一定要注意,先把周围点都染成白色再找未染色的点...不要染了一个白色之后就跟着找这个白色的出度...

    代码

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    
    const int N = 3e5;
    
    int n, m;
    vector<int> g[N + 10];
    int vis[N + 10],flag[N + 10],cnt;
    queue<int> dl;
    
    void dfs(int x){
        cnt++;
        vis[x] = 1;
        int len = g[x].size();
    
        vector<int> v;
        v.clear();
    
        for (int i = 0;i < len; i++){
            int y = g[x][i];
            if (vis[y] == 0){
                continue;
            }
            vis[y] = 0;
            v.push_back(y);
        }
    
        for (int y:v){
            int len2 = g[y].size();
            for (int j = 0;j < len2; j++){
                int yy = g[y][j];
                if (vis[yy] == -1){
                    dl.push(yy);
                }
            }
        }
    
    }
    
    int main() {
    	#ifdef LOCAL_DEFINE
    		freopen("in.txt", "r", stdin);
    	#endif
    	ios::sync_with_stdio(0), cin.tie(0);
    	int T;
    	cin >> T;
    	while (T--) {
            cin >> n >> m;
            for (int i = 1;i <= n; i++){
                g[i].clear();
                vis[i] = -1;
                flag[i] = 0;
            }
            for (int i = 1;i <= m; i++){
                int u, v;
                cin >> u >> v;
                g[u].push_back(v);
                g[v].push_back(u);
            }
            cnt = 0;
            dl.push(1);
            while (!dl.empty()){
                int x = dl.front();dl.pop();
                if (vis[x] == -1){
                    dfs(x);
                }
            }
            bool ok = true;
            for (int i = 1;i <= n; i++){
                if (vis[i] == -1){
                    ok = false;
                    break;
                }
            }
            if (!ok){
                cout << "NO" << endl;
                continue;
            }
            cout << "YES" << endl;
            cout << cnt << endl;
            for (int i = 1;i <= n; i++){
                if (vis[i] == 1){
                    cout << i << " ";
                }
            }
            cout << endl;
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    odoo开发笔记 -- 后台代码什么时候需要注意编码格式
    mysql添加类似oracle的伪列及查看表信息
    windows10升级系统后,无法远程桌面连接服务器
    时间管理
    odoo开发笔记 -- odoo仪表板集成hightcharts
    odoo开发笔记 -- odoo10 视图界面根据字段状态,动态隐藏创建&编辑按钮
    odoo开发笔记 -- odoo源码下载地址(非官方)
    odoo开发笔记 -- 异常信息处理汇总
    macbook 安装oracle RAC
    ubuntu升级pip后, ImportError: cannot import name ‘main‘
  • 原文地址:https://www.cnblogs.com/AWCXV/p/14291320.html
Copyright © 2011-2022 走看看