BZOJ3331 BZOJ2013 压力

考前挣扎

圆方树这么早就出现了嘛。。。

要求每个点必须被经过的次数 所以就是路径上的割点/端点++

由于圆方树上所有非叶子圆点都是割点 所以就是树上差分就可以辣。

实现的时候出了一点小问题。

就是这里

if(low[y] == dfn[x])
{
    int r = ++poi,w;
    do
    {
        w = stk.top(); stk.pop();
        att(r,w);//printf("QAQ");
    }while(w!=y);
    att(r,x);
}
if(low[y] == dfn[x])
{
    int r = ++poi;
    while(stk.top()!=x)
    {
        int w = stk.top(); stk.pop();
        att(r,w);//printf("QAQ");
    }
    att(r,x);
}

后面这个是错哒 因为x与y之间可以有别的未弹栈的点的qwq

要注意!

//Love and Freedom.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#define ll long long
#define inf 20021225
#define mxn 210000
using namespace std;
 
struct edge{int to,lt;}e[mxn<<1],t[mxn<<2];
int in[mxn],cnt,it[mxn<<1],tnt,poi;
void add(int x,int y)
{
    e[++cnt].to = y; e[cnt].lt=in[x]; in[x] = cnt;
    e[++cnt].to = x; e[cnt].lt=in[y]; in[y] = cnt;
}
 
void att(int x,int y)
{
    t[++tnt].to = y; t[tnt].lt=it[x]; it[x] = tnt;
    t[++tnt].to = x; t[tnt].lt=it[y]; it[y] = tnt;
}
 
int dfn[mxn],low[mxn],tot;
stack<int> stk;
void dfs(int x)
{
    dfn[x] = low[x] = ++tot; stk.push(x);
    for(int i=in[x];i;i=e[i].lt)
    {
        int y = e[i].to;
        if(dfn[y])  low[x] = min(low[x],dfn[y]);
        else
        {
            dfs(y);
            if(low[y] == dfn[x])
            {
                int r = ++poi,w;
                do
                {
                    w = stk.top(); stk.pop();
                    att(r,w);//printf("QAQ");
                }while(w!=y);
                att(r,x);
            }
            low[x] = min(low[x],low[y]);
        }
    }
}
int key[mxn<<1],ans[mxn<<1],fa[mxn][20];
int dep[mxn<<1];
void build(int x,int f)
{
    dep[x] = dep[f]+1;
    for(int i=1;i<20;i++)
        fa[x][i] = fa[fa[x][i-1]][i-1];
    for(int i=it[x];i;i=t[i].lt)
    {
        int y = t[i].to;
        if(y == f)  continue;
        fa[y][0] = x;build(y,x);
    }
}
 
void dfs(int x,int f)
{
    //if(x<=n)   dis[x] = dis[f] +1;
    //else  dis[x] = dis[f];
    //int flag = 0;
    for(int i=it[x];i;i=t[i].lt)
    {
        int y = t[i].to; if(y==f)   continue;
        dfs(y,x); ans[x] += ans[y];
    }
    ans[x] += key[x];
    //if(!flag) dis[x] --;
}
 
int lca(int x,int y)
{
    if(dep[x] < dep[y])  swap(x,y);
    int del = dep[x] - dep[y];
    for(int i=19;~i;i--)    if(del&(1<<i))
        x = fa[x][i];
    //printf("%d %d\n",dep[x],dep[y]);
    if(x==y)    return x;
    for(int i=19;~i;i--)    if(fa[x][i]!=fa[y][i])
        x=fa[x][i],y=fa[y][i];
    //printf("%d\n",x);
    return fa[x][0];
}
 
int main()
{
    int n,m,q,x,y;
    scanf("%d%d%d",&n,&m,&q);
    poi = n;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
    }
    dfs(1); build(1,1);
    //printf("%d\n",poi);
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&x,&y);
        key[x]++; key[y]++;
        int LCA = lca(x,y);
        key[fa[LCA][0]]--;
        key[LCA]--;
    }
    dfs(1,1);
    for(int i=1;i<=n;i++)
        printf("%d\n",ans[i]);
    return 0;
}

 

posted @ 2019-01-18 08:11  寒雨微凝  阅读(137)  评论(0编辑  收藏  举报