zoukankan      html  css  js  c++  java
  • (dfs)codeforces 767C

    题意:

    一棵树,每个节点有一个权值t,把它分成三部分,每部分要求权值和相等。

    分析:

    先可以先算出总大小sum。

    接着%3看能不能分,不能-1,能继续。

    然后递归算出每个子树的权值和。

    一开始想到直接找出两个sum/3就行了,后来发现还会可能有两个分点输出祖辈关系。

    想到半天,感觉很容易dfs写,,,,然而想了半天不知道怎么写,,好久不写题,自己好辣鸡- -

    后来想到一种方法,一开始记录好每个节点的父节点,先找出所有的sum/3扔到set里,然后从每个sum/3节点出发向上找,一旦找到sum/3*2即可,如果遇到sum/3,就把它去掉,如果没找到sum/3*2,就看最后留下的sum/3有几个,如果大于等于2,就输出前两个,否则-1,中间如果怕超时,加个bool数组记录一下,这样也只是把所有点扫一遍而已。

    其实更简单的方法是直接两次dfs,第一找出来一个sum/3,然后子树结果清零,然后再dfs一次,直接忽视掉前一个sum/3,找出第二个sum/3,如果能找出来就输出,不能就-1。

    唉,感觉自己思维江化了。

    代码(两种思路,第二种最简单了,,):

      1 #include <set>
      2 #include <map>
      3 #include <list>
      4 #include <cmath>
      5 #include <queue>
      6 #include <vector>
      7 #include <bitset>
      8 #include <string>
      9 #include <cctype>
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <cstdlib>
     13 #include <iostream>
     14 #include <algorithm>
     15 
     16 using namespace std;
     17 
     18 typedef long long ll;
     19 typedef unsigned long long ull;
     20 #define inf (0x3f3f3f3f)
     21 #define lnf (0x3f3f3f3f3f3f3f3f)
     22 #define eps (1e-6)
     23 int sgn(double a) {
     24     return a < -eps ? -1 : a < eps ? 0 : 1;
     25 }
     26 
     27 //--------------------------
     28 
     29 const int maxn = 1000010;
     30 
     31 
     32 set<int> ans;
     33 vector<int> v[maxn];
     34 int tem[maxn];
     35 int par[maxn];
     36 bool vis[maxn];
     37 int n;
     38 int s;
     39 
     40 bool dfs(int u) {
     41     for(int i=0; i<v[u].size(); i++) {
     42         dfs(v[u][i]);
     43         tem[u]+=tem[v[u][i]];
     44     }
     45 }
     46 
     47 int dfs2(int u) {
     48     if(u==s||vis[u])return -1;
     49     vis[u]=true;
     50     if(tem[u]==tem[s]/3*2) {
     51         return u;
     52     }
     53     if(tem[u]==tem[s]/3) {
     54         ans.erase(u);
     55     }
     56     dfs2(par[u]);
     57 }
     58 
     59 
     60 
     61 void solve() {
     62     scanf("%d",&n);
     63     int u,t;
     64     memset(vis,0,sizeof(vis));
     65     for(int i=1; i<=n; i++) {
     66         scanf("%d%d",&u,&t);
     67         par[i]=u;
     68         if(u!=0) {
     69             v[u].push_back(i);
     70         } else {
     71             s=i;
     72         }
     73         tem[i]=t;
     74     }
     75     dfs(s);
     76     if(tem[s]%3==0) {
     77         for(int i=1; i<=n; i++) {
     78             if(i==s)continue;
     79             if(tem[i]==tem[s]/3)ans.insert(i);
     80         }
     81         for(set<int>::iterator it=ans.begin(); it!=ans.end(); it++) {
     82             int res=dfs2(par[*it]);
     83             if(res!=-1) {
     84                 printf("%d %d
    ",*it,res);
     85                 return;
     86             }
     87         }
     88         if(ans.size()>=2) {
     89             set<int>::iterator ita=ans.begin();
     90             int a=*ita;
     91             ita++;
     92             int b=*ita;
     93             printf("%d %d
    ",a,b);
     94         } else {
     95             puts("-1");
     96         }
     97     } else {
     98         puts("-1");
     99     }
    100 }
    101 
    102 int main() {
    103 
    104 #ifndef ONLINE_JUDGE
    105     freopen("1.in", "r", stdin);
    106     //freopen("1.out", "w", stdout);
    107 #endif
    108     //iostream::sync_with_stdio(false);
    109     solve();
    110     return 0;
    111 }
    #include <set>
    #include <map>
    #include <list>
    #include <cmath>
    #include <queue>
    #include <vector>
    #include <bitset>
    #include <string>
    #include <cctype>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    #define inf (0x3f3f3f3f)
    #define lnf (0x3f3f3f3f3f3f3f3f)
    #define eps (1e-6)
    int sgn(double a) {
        return a < -eps ? -1 : a < eps ? 0 : 1;
    }
    
    //--------------------------
    
    const int maxn = 1000010;
    
    
    vector<int> v[maxn];
    int tem1[maxn],tem2[maxn];
    int sum;
    int n;
    int s;
    bool flag1,flag2;
    int res1,res2;
    
    void dfs(int u) {
        for(int i=0; i<v[u].size(); i++) {
            dfs(v[u][i]);
            if(flag1)return ;
            tem1[u]+=tem1[v[u][i]];
        }
        if(u!=s&&tem1[u]==sum/3) {
            flag1=true;
            res1=u;
        }
    }
    
    void dfs2(int u) {
        for(int i=0; i<v[u].size(); i++) {
            if(flag1&&v[u][i]==res1) {
                continue;
            }
            dfs2(v[u][i]);
            if(flag2)return ;
            tem2[u]+=tem2[v[u][i]];
        }
        if(u!=s&&tem2[u]==sum/3) {
            flag2=true;
            res2=u;
        }
    }
    
    
    
    void solve() {
        scanf("%d",&n);
        int u,t;
        sum=0;
        flag1=flag2=false;
        for(int i=1; i<=n; i++) {
            scanf("%d%d",&u,&t);
            if(u!=0) {
                v[u].push_back(i);
            } else {
                s=i;
            }
            tem1[i]=tem2[i]=t;
            sum+=t;
        }
        if(sum%3!=0) {
            puts("-1");
            return;
        }
        dfs(s);
        if(!flag1) {
            puts("-1");
            return;
        }
        dfs2(s);
        if(!flag2) {
            puts("-1");
            return;
        } else {
            printf("%d %d
    ",res1,res2);
        }
    
    }
    
    int main() {
    
    #ifndef ONLINE_JUDGE
        freopen("1.in", "r", stdin);
        //freopen("1.out", "w", stdout);
    #endif
        //iostream::sync_with_stdio(false);
        solve();
        return 0;
    }
  • 相关阅读:
    linux命令之------touch命令
    linux命令之------rm命令
    linux命令之------Mv命令
    linux命令之------Less命令
    linux命令之------More命令
    linux命令之------Find命令
    linux命令之------Chown命令
    linux命令之------Chmod命令
    linux命令之------Cat命令
    linux命令之------Wc命令(word count)
  • 原文地址:https://www.cnblogs.com/tak-fate/p/6423768.html
Copyright © 2011-2022 走看看