Codeforces 767C. Garland (dfs)

题目链接:

http://codeforces.com/problemset/problem/767/C

题意:

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

思路:

由于子树的子树里再出现等于sum/3的情况,那么dp[u]=0,就可以很好的避免计算情况了

dfs  第一找出来一个sum/3,然后子树结果清零,然后再dfs一次,直接忽视掉前一个sum/3,找出第二个sum/3,如果能找出来就输出,不能就-1。

还有一种笨写法。(傻逼的我调了半辈子)

代码:

代码一:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MS(a) memset(a,0,sizeof(a))
#define MP make_pair
#define PB push_back
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
    ll x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 1e5+10;

int n,s,x,dp[maxn],ans1,ans2,sum;
vector<int> g[maxn];

void dfs(int u){
    for(int i=0; i<(int)g[u].size(); i++){
        dfs(g[u][i]);
        dp[u] += dp[g[u][i]];
    }
    if(dp[u]==sum/3 && u!=s){
        if(!ans1) { ans1=u; dp[u]=0;}
        else if(!ans2) { ans2=u; return ;}
    }
}

int main()
{
    cin >> n;
    sum = 0;
    for(int i=1; i<=n; i++){
        scanf("%d%d",&x,&dp[i]);
        if(x==0) s = i;
        else g[x].push_back(i);
        sum += dp[i];
    }
    if(sum%3) return puts("-1"),0;

    dfs(s);
    if(!ans1 || !ans2) return puts("-1"),0;
    else cout<<ans1<<" "<<ans2<<endl;

    return 0;
}

代码二:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MS(a) memset(a,0,sizeof(a))
#define MP make_pair
#define PB push_back
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
    ll x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 1e6+10;
int n;
vector<int> mp[maxn];
int vis[maxn];
int val[maxn];
int v[maxn];
int avg;
int ans1,ans2,s;

//int tem1[maxn],tem2[maxn];
//bool flag1,flag2;

int dfs1(int st){
    if(vis[st] || st==ans1)
        return 0;
    vis[st]=1;
    val[st]=v[st];
    for(int i=0; i<(int)mp[st].size(); i++){
        int u = mp[st][i];
        if(u == ans1) continue;
        val[st]+=dfs1(u);
    }
    return val[st];
}

void dfs2(int st){
    if(ans1 != 0) return ;
    for(int i=0; i<(int)mp[st].size(); i++){
        dfs2(mp[st][i]);
        if(ans2 != 0) return ;
    }
    if(ans1==0 && val[st]==avg && st!=s)
        ans1 = st;
}

void dfs3(int st){
    if(ans2 != 0) return ;
    for(int i=0; i<(int)mp[st].size(); i++){
        if(mp[st][i]==ans1) continue;
        dfs3(mp[st][i]);
        if(ans2 != 0) return ;
    }
    if(ans2==0 && val[st]==avg && st!=s && st!=ans1)
        ans2 = st;
}
//void dfs2(int u) {
//    for(int i=0; i<mp[u].size(); i++) {
//        dfs2(mp[u][i]);
//        if(flag1)return ;
//        tem1[u]+=tem1[mp[u][i]];
//    }
//    if(u!=s&&tem1[u]==avg) {
//        flag1=true;
//        ans1=u;
//    }
//}
//
//void dfs3(int u) {
//    for(int i=0; i<mp[u].size(); i++) {
//        if(flag1&&mp[u][i]==ans1) {
//            continue;
//        }
//        dfs3(mp[u][i]);
//        if(flag2)return ;
//        tem2[u]+=tem2[mp[u][i]];
//    }
//    if(u!=s&&tem2[u]==avg) {
//        flag2=true;
//        ans2=u;
//    }
//}

int main()
{
    cin >> n;
    for(int x,val,i=1;i<=n;i++){
        scanf("%d%d",&x,&v[i]);
//        tem1[i] = tem2[i] = v[i];
        if(x == 0) s = i;
        else mp[x].push_back(i);
    }
    dfs1(s);
    avg=val[s]/3;
    if(val[s]%3){
        cout << -1 << endl;
        return 0;
    }
    dfs2(s);
    if(ans1==0) return puts("-1"),0;
    memset(vis,0,sizeof(vis));
    dfs1(s);
    dfs3(s);
    if(ans2==0) return puts("-1"),0;
    cout << ans1 << " " << ans2 << endl;
}
时间: 2024-08-10 15:39:40

Codeforces 767C. Garland (dfs)的相关文章

CodeForces 767C Garland

树形$dp$. 先看权值之和是否为$3$的倍数,如果不是则一定无解. 如果是$3$的倍数,可以分两次去切.每次一个节点,要求这个节点不是根,并且的子树权值和为$sum/3$,又要是深度最深的. 找不到两个依然是无解,否则就有解. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #incl

Codeforces 104C Cthulhu dfs暴力 || 双连通缩点

题目链接:点击打开链接 题意: 给定n个点m条边的无向图 问图中是否存在 有且仅有一个简单环和一些树,且这些树的root都在这个简单环上. 瞎写了个点双..== #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <vector> #include <set> us

CodeForces 731C Socks (DFS或并查集)

题意:有n只袜子,k种颜色,在m天中,问最少修改几只袜子的颜色,可以使每天穿的袜子左右两只都同颜色. 析:很明显,每个连通块都必须是同一种颜色,然后再统计最多颜色的就好了,即可以用并查集也可以用DFS. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include

Codeforces 723d [暴力dfs]

/* 不要低头,不要放弃,不要气馁,不要慌张. 题意: 给n,m和k,n和m为所给矩阵的高和宽.k是要求最多剩下的湖的数量. 在所给的矩阵中,*代表陆地,.代表水. 湖的定义是一片连续的水(上下左右四个方向),并且水不含边界. 水含边界的情况被成为海. 问最少填多少湖的面积,使得湖的数量减少到k... 思路: 水dfs,记录有多少湖,并且记录每个湖的面积,然后排下序贪心就好. 坑: 做题一定别急一定别急一定别急一定知道自己写的是什么!!!! */ #include<bits/stdc++.h>

Codeforces 27B - Tournament (dfs)

题意 有n支队伍,他们之间所有队伍都要打一遍,其中有一对的结果没有给出,求这场比赛的结果. 思路 显然我们能从给出的这些对求出有哪两个队伍没给出. 然后就是要判断这两队的胜负情况,dfs判断一下有向图中其中一个是不是能到达另一个就可以了. 代码 #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #inc

CodeForces 378C Maze (DFS)

题目链接 题意:给一个由“.”组成的联通区域,求再添加k个‘#'以后还是联通区域的方案. 分析:做题的时候犯二了,用DFS,一直搜到边缘,然后从边缘依次往回 回溯,回溯的过程中填充’#‘ 一直填充k个. 因为在搜索的过程中,一直都是vis[][]标记的,所以时间复杂度最多只是搜了所有的边,即500*500*4. DFS搜索的时间复杂度,取决于边的个数. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring&

CodeForces 570D 【dfs序】

题意: 给一颗树,根节点深度为1,每一个节点都代表一个子母. 数据输入: 节点数 询问数 从编号为2的节点开始依次输入其父节点的编号(共有节点数减1个数字输入) 字符串有节点数个小写字母 接下来询问 a b 代表以a为根节点的子树在深度为b(包含)的范围内所有节点的字母能否组成回文串. 能输出Yes,不能输出No 思路: 1.dfs序,对于每个节点,我们在深度和字母组成的二维数组里边记录进入节点和离开节点的时间戳. 2.用到upper_bound和lower_bound函数对该深度之下各个时间的

CodeForces 580C 树+dfs搜索

Description Kefa decided to celebrate his first big salary by going to the restaurant. He lives by an unusual park. The park is a rooted tree consisting of n vertices with the root at vertex 1. Vertex 1 also contains Kefa's house. Unfortunaely for ou

CodeForces - 697D - Puzzles DFS

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify; font: 10.5px "Trebuchet MS"; color: #000000 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify; text-indent: 21.0px; font: 10.5px "PingFang SC"; color: #000000 } p