HDU_4912 Path on the tree 2014多校5 贪心+LCA

当时刚学LCA-tarjan不久,就比赛有这个题,但没想到还是没做出来。。一开始以为是DP来着,没想到是贪心,想想也对,从树的最下层开始,每次遇到询问的点,就找到他们的LCA(路径里面必经LCA),然后把该LCA下的子树连同自己全部染色为不可用了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int N = (100000+10)*2;
int u[N],v[N],ft[N],nt[N],cnt;
int dep[N];
vector<int> G[N];
void add(int a,int b)
{
    u[cnt]=a;
    v[cnt]=b;
    nt[cnt]=ft[a];
    ft[a]=cnt++;
}
int f[N];
int anc[N];
int vis[N],col[N];
struct edge
{
    int a,b,anc,dep;
    bool operator < (const edge& rhs) const{
        return dep>rhs.dep;
    }
}E[N];
int findset(int x)
{
    if (x!=f[x]){
       f[x]=findset(f[x]);
    }
    return f[x];
}
int unionset(int a,int b)
{
    int r1=findset(a);
    int r2=findset(b);
    if (r1==r2) return r1;
    f[r2]=r1;
    return r1;
}
void tarjan(int x,int fa)
{
    anc[x]=x;
    for (int i=ft[x];i!=-1;i=nt[i]){
        int nx=v[i];
        if (nx==fa) continue;
        tarjan(nx,x);
        int rt=unionset(x,nx);
        anc[rt]=x;
    }
    col[x]=1;
    for (int i=0;i<G[x].size();i++){
        int ii=G[x][i];
        int nx=E[ii].a^E[ii].b^x;
        if (col[nx]){
            E[ii].anc=findset(nx);
            E[ii].dep=dep[E[ii].anc];

        }
    }
}
void dfs1(int x,int fa,int d)
{
    dep[x]=d;
    for (int i=ft[x];i!=-1;i=nt[i]){
        int vx=v[i];
        if (vx==fa) continue;
        dfs1(vx,x,d+1);
    }
}
void dfs2(int x)
{
    vis[x]=1;
    for (int i=ft[x];i!=-1;i=nt[i]){
        int vx=v[i];
        if (dep[vx]<dep[x] || vis[vx]) continue;
        dfs2(vx);
    }
}
int main()
{
    int n,m,a,b;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        memset(ft,-1,sizeof(ft));
        memset(vis,0,sizeof(vis));
        memset(col,0,sizeof(col));
        cnt=0;
        for (int i=1;i<n;i++){
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
            G[i].clear();
            f[i]=i;
        }
        dfs1(1,-1,0);
        G[n].clear();
        f[n]=n;
        for (int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            G[a].push_back(i);
            G[b].push_back(i);
            E[i].a=a;
            E[i].b=b;
        }
        tarjan(1,-1);
        sort(E,E+m);
        int ans=0;
        for (int i=0;i<m;i++){
            if (!vis[E[i].a] && !vis[E[i].b]){
                ans++;
                dfs2(E[i].anc);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-16 13:40:48

HDU_4912 Path on the tree 2014多校5 贪心+LCA的相关文章

2014多校第六场 1005 || HDU 4925 Apple Tree

题目链接 题意 : 给你一块n×m的矩阵,每一个格子可以施肥或者是种苹果,种一颗苹果可以得到一个苹果,但是如果你在一个格子上施了肥,那么所有与该格子相邻(指上下左右)的有苹果树的地方最后得到的苹果是两倍,如果(i,j)有一颗苹果树,(i-1,j)与(i,j+1)施了肥,那么苹果应该是1的两倍2,2的两倍4,最后是4个苹果,问你怎么安排苹果和施肥的格子使最后得到的苹果最多. 思路 : 画了图就可以看出来,苹果和苹果,肥与肥之间不要相邻就好了,所有的苹果之间都有施肥,所有施肥的格子都被苹果隔开了才能

2014多校联合六(HDU 4923 HDU 4925 HDU 4927 HDU 4930)

HDU 4923 Room and Moor 题意:给出A序列  求满足题目所写的B序列  使得方差最小 思路:可以想到最后的结果中  B序列的值一定是一段一段的  那么我们可以类似贪心去搞  对于一段序列我们可以求出什么样的b值使得方差最小  即序列中1的个数除以序列长度  又因为B是单调的  可以用一个单调栈去模拟  复杂度远远小于n^2  不要被吓怕- 代码: #include<cstdio> #include<cstring> #include<algorithm&g

2014多校联合-第六场

最近这两场好无奈啊... 今天这场最后30分钟敲1001,压力倍增,虽然思路比较明确,但是代码打起来不怎么容易. 但是还是好在25分钟左右debug结束.提交wa,再提交,依然WA.......最后5分钟,还是没有AC掉. 一开始以为是精度问题,后来才sb的发现原来数组开小了. 在压力环境下保证代码的效率和质量真不是一件容易的事情.不过数组开小了,真是不可原谅. 1001:Map 题目相当于几条链表.把链表排成几行. 然后枚举每一列的状态会被操作多少次. 然后把和累加起来,然后直接除以状态总数.

2014多校联合4

1002:Redraw Beautiful Drawings 最大流....用sap+gap优化的模版过的... 1. 源点 -> 每一行对应的点,流量限制为该行的和 2. 每一行对应的点 -> 每一列对应的点,流量限制为 K 3. 每一列对应的点 -> 汇点,流量限制为该列的和 跑一遍最大流. 如果流量小于总权值和,那么说明impossible. 如果等于: 构建残图网络,如果残图网络可以形成一条回路,那么说明有多解. #include <stdio.h> #include

hdu 4970 Killing Monsters(简单题) 2014多校训练第9场

Killing Monsters                                                                        Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Kingdom Rush is a popular TD game, in which you should b

2014多校1011--hdu--4097--Killing Monsters(塔防,线段树超时。。)

Killing Monsters Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 107    Accepted Submission(s): 54 Problem Description Kingdom Rush is a popular TD game, in which you should build some towers

2014多校7(1006)hdu4940(有上下界的最大流)

Destroy Transportation system Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 114    Accepted Submission(s): 83 Problem Description Tom is a commander, his task is destroying his enemy's tran

HDU 4864 Task(2014多校--贪心)

Task 比赛当时思路想的差不多,感觉能过的,该处理的也都处理到了,最后还是没过,可能是二分写错了吧-.- 大意:给你n个机器,m个要完成的任务,每个机器跟任务都有两个属性,机器是最大工作时间跟等级,任务是需要工作的时间跟等级.完成一个任务可以得到500*(工作时间)+2*(等级)的报酬.完成任务的条件是机器的工作时间满足任务的需要,等级要大于等于任务的等级,一个机器只能用一次,一个任务也只能用一个机器去完成.需要进行策略选择,使得完成更多的任务. 思路:开始想的就是贪心,也想到了贪心的时候时间

Codechef:Path Triples On Tree

Path Triples On Tree 题意是求树上都不相交或者都相交的路径三元组数量. 发现blog里没什么树形dp题,也没有cc题,所以来丢一道cc上的树形dp题. 比较暴力,比较恶心 #include<cstdio> #include<algorithm> #define MN 300001 #define ui long long using namespace std; ui read_p,read_ca; inline ui read(){ read_p=0;read