zoukankan      html  css  js  c++  java
  • C. Timofey and a tree 观察题 + dfs模拟

    http://codeforces.com/contest/764/problem/C

    题意:在n个顶点中随便删除一个,然后分成若干个连通子图,要求这若干个连通子图的颜色都只有一种。

    记得边是双向的,wa15的可能是不知道边是双向的吧。

    一个观察:如果某条边连接的两个顶点的颜色不同,那么可以看看删除这两个顶点,成立就成立,不成立就不成立。

    因为必定要把这两个顶点分开。

    然后就是暴力dfs了。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    
    const int maxn = 2e6 + 20;
    struct node {
        int u, v, tonext;
    }e[maxn];
    int num;
    int first[maxn];
    void add(int u, int v) {
        num++;
        e[num].u = u;
        e[num].v = v;
        e[num].tonext = first[u];
        first[u] = num;
    }
    int c[maxn], in[maxn];
    int u[maxn], v[maxn];
    set<int>ss;
    int vis[maxn];
    int DFN;
    int dfs(int cur, int no) {
        ss.insert(c[cur]);
        if (ss.size() >= 2) return false;
        bool flag = true;
        for (int i = first[cur]; i; i = e[i].tonext) {
            if (e[i].v == no) continue;
            if (vis[e[i].v] == DFN) continue;
            vis[e[i].v] = DFN;
            flag = flag && dfs(e[i].v, no);
        }
        return flag;
    }
    bool del(int cur) {
        for (int i = first[cur]; i; i = e[i].tonext) {
            ss.clear();
            DFN++;
            vis[cur] = DFN;
            vis[e[i].v] = DFN;
            if (dfs(e[i].v, inf) == false) return false;
        }
        return true;
    }
    void work() {
        int n;
        cin >> n;
        for (int i = 1; i <= n - 1; ++i) {
            cin >> u[i] >> v[i];
        }
        for (int i = 1; i <= n; ++i) {
            cin >> c[i];
        }
        int which = inf;
        for (int i = 1; i <= n - 1; ++i) {
            if (c[u[i]] != c[v[i]] && which == inf) which = i;
            add(u[i], v[i]);
            add(v[i], u[i]);
        }
        if (which == inf) {
            cout << "YES" << endl;
            cout << 1 << endl;
            return;
        }
    //    cout << which << "  " << root << endl;
        if (del(u[which])) {
            cout << "YES" << endl;
            cout << u[which] << endl;
            return;
        }
        if (del(v[which])) {
            cout << "YES" << endl;
            cout << v[which] << endl;
            return;
        }
        cout << "NO" << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    给定一个十进制数M,以及需要转换的进制数N。 将十进制数M转化为N进制数
    java计算两条线段交点
    输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m 转载
    全排列 (递归求解+字典序) java 转载
    四大线程池详解(转载)
    生产者消费者简单实现(转载)
    进程 线程通信方式(转载)
    匿名对象和类名为数据类型(java)
    星星(java)
    杨辉三角(java)
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6363864.html
Copyright © 2011-2022 走看看