2020-2021 ACM-ICPC, Asia Seoul Regional Contest

C. Dessert Café:

题意: 给你一个N个节点的树,树上有m个房子,问树上有几个节点是在两个房子之间的。

思路:我们发现只要是该节点的子树里包括了所有节点或者只有一个节点,那么这个结点肯定不是在两个房子之间的,至于证明我们可以画几幅图证明。代码实现的话,需要用到num[]数组记录该节点子树里房子个数,然后dfs一边即可。

代码:

 

int n,k;
vector<int>mp[maxn];
int num[maxn]; 
bool isA[maxn];
int ans=0;
void dfs(int u,int f)
{
    int cnt=0;
    for(int i=0;i<mp[u].size();i++)
    {
        int v=mp[u][i];
        if(v!=f)
        {
            dfs(v,u);
            num[u]+=num[v];
            if(num[v]) cnt++;
        }
    }
    if(num[u]!=k) cnt++;
    //dbg(u);
    if(cnt>=2&&!isA[u])  ans++;
    //dbg(ans);
}
void run()
{
    n=rd();
    k=rd();
    for(int i =1;i<n;i++)
    {
        int u=rd(),v=rd(),w=rd();
        mp[u].push_back(v);
        mp[v].push_back(u);
    }
    for(int i=0;i<k;i++)
    {
        int x=rd();
        num[x]=1;
        isA[x]=true;
        ans++;
        //cout<<ans<<" sss"<<endl;
    }
    dfs(1,-1);
    cout<<ans<<endl;
}
signed main()
{    
    run();
    return 0;
}

 

 

 

 

E - Imprecise Computer

思路:通过分析不难发现如果前面产生了1>2的错误判断,那么这个错误会一直影响到最后,然后我们只要在产生这样错误后对后面的d +1或者-1 直到最后消除影响,那么就可以构造成功,而且中途是不能出现d>=2 的情况。

代码实现:

int n;
int d[maxn];
void run()
{
    n=rd();
    for(int i=1;i<=n;i++) d[i]=rd();
    bool flag=true;
    for(int i=1;i<=n;i++)
    {
        if(d[i]>1) {
            puts("NO");
            return ;
        }else if(d[i])
        {
            if(d[i+1]) d[i+1]--;
            else d[i+1]--;
        }
    }
    puts(d[n]==0?"YES":"NO");
}
signed main()
{    
//  int t=rd();
//  while(t--) 
    run();
    return 0;
}

 

posted @ 2021-01-27 19:30  JamZF  阅读(556)  评论(0编辑  收藏  举报