hdu2460 和 poj3694

来源:互联网 发布:网络 党建 编辑:程序博客网 时间:2024/05/16 08:15
poj3694:先预处理出询问边(u,v)的最小公共祖先lca{u,v}(用tarjan的lca离线算法)和桥的总数scc,最后每次从u到lca{u,v},v到lca{u,v},找出其中桥的数量,用scc减去,就是答案了。因为每次形成了圈,所以用并查集缩点,不然会TLE;写了一天就T在这儿了。

hdu2460:尼玛啊?hdu太坑爹了,个种深搜都不行啊? 连并查集路径压缩 的深搜都不行 害我改了一晚上…各种RE啊?其它和poj3694一样。

//poj3694 代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 100005
#define maxc 400005
usingnamespace std;
structnode
{
    inte,next;
}edge[maxc],Tedge[2005];
structnode1
{
    inta,b;
}qurey[1005],fa[INF];
intnum,top,scc,bleg[INF],st[INF],first1[INF],first[INF],dfn[INF],low[INF],blegs[INF];
intused[INF],edges[maxc],ancestor[INF],lca[2005],ids[maxc],fids[maxc],ids1[maxc],fids1[maxc];
intFind(intx)
{
    returnbleg[x]==x?x:bleg[x]=Find(bleg[x]);
}
voidUnion(inta,intb)
{
    a=Find(a),b=Find(b);
    bleg[b]=a;
}
intFinds(intx)
{
    returnblegs[x]==x?x:blegs[x]=Finds(blegs[x]);
}
voidUnions(inta,intb)
{
    a=Finds(a),b=Finds(b);
    blegs[a]=b;
}
voidtarjan(intv)
{
    dfn[v]=low[v]=++num;
    st[++top]=v;
    ancestor[Find(v)]=v;
    for(inti=first[v];i!=-1;i=edge[i].next)
    {
        intu=edge[i].e;
        if(fids[ids[i]])
        continue;
        fids[ids[i]]=1;
        if(!dfn[u])
        {
            fa[u].a=v,fa[u].b=i;
            tarjan(u);
            Union(v,u);
            ancestor[Find(v)]=v;
            low[v]=min(low[v],low[u]);
            if(low[u]>dfn[v])
            {
                scc++;
                edges[ids[i]]=1;
                while(true)
                {
                    intx=st[top--];
                    if(x==u)
                    break;
                }
            }
        }
        else
        low[v]=min(low[v],dfn[u]);
    }
    used[v]=1;
    for(inti=first1[v];i!=-1;i=Tedge[i].next)
    if(used[Tedge[i].e] && !fids1[ids1[i]])
    {
        lca[ids1[i]]=ancestor[Find(Tedge[i].e)];
        fids1[ids1[i]]=1;
    }
}
intmain()
{
    intn,m,q,cas=0;
    while(scanf("%d%d",&n,&m),m+n)
    {
        cas++;
        memset(first,-1,sizeof(first));
        memset(first1,-1,sizeof(first1));
        memset(dfn,0,sizeof(dfn));
        memset(edges,0,sizeof(edges));
        memset(fids,0,sizeof(fids));
        memset(fids1,0,sizeof(fids1));
        memset(used,0,sizeof(used));
        inta,b,nume,number;
        number=nume=top=scc=num=0;
        for(inti=1;i<=n;i++)
        blegs[i]=fa[i].a=bleg[i]=i;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            ids[nume]=number;
            edge[nume].e=b,edge[nume].next=first[a],first[a]=nume++;
            ids[nume]=number++;
            edge[nume].e=a,edge[nume].next=first[b],first[b]=nume++;
        }
        number=nume=0;
        scanf("%d",&q);
        for(inti=0;i<q;i++)
        {
            scanf("%d%d",&a,&b);
            qurey[i].a=a,qurey[i].b=b;
            ids1[nume]=number;
            Tedge[nume].e=b,Tedge[nume].next=first1[a],first1[a]=nume++;
            ids1[nume]=number++;
            Tedge[nume].e=a,Tedge[nume].next=first1[b],first1[b]=nume++;
        }
        tarjan(1);
        printf("Case %d:n",cas);
        for(inti=0;i<q;i++)
        {
            if(scc!=0)
            {
                for(intk=qurey[i].a,j=Finds(fa[k].a);j!=Finds(qurey[i].a);k=j,j=Finds(fa[j].a))
                {
                    Unions(qurey[i].a,j);
                    if(edges[ids[fa[k].b]])
                    {
                        scc--;
                        edges[ids[fa[k].b]]=0;
                    }
                    if(j==Find(lca[i]))
                    break;
                }
                for(intk=qurey[i].b,j=Finds(fa[k].a);j!=Finds(qurey[i].b);k=j,j=Finds(fa[j].a))
                {
                    Unions(qurey[i].b,j);
                    if(edges[ids[fa[k].b]])
                    {
                        scc--;
                        edges[ids[fa[k].b]]=0;
                    }
                    if(j==Finds(lca[i]))
                    break;
                }
                Union(qurey[i].a,qurey[i].b);
            }
            printf("%dn",scc);
        }
        printf("n");
    }
    return0;
}
 

//hdu2460  代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 100005
#define maxc 400005
usingnamespace std;
structnode
{
    inte,next;
}edge[maxc],Tedge[2005];
structnode1
{
    inta,b;
}qurey[1005],fa[INF];
intnum,top,scc,bleg[INF],st[INF],first1[INF],first[INF],dfn[INF],low[INF],blegs[INF],vis[INF];
intused[INF],edges[maxc],ancestor[INF],lca[2005],ids[maxc],fids[maxc],ids1[maxc],fids1[maxc];
intFind(intx)
{
    inty=x;
    while(y!=bleg[y])
    y=bleg[y];
    while(x!=bleg[x])
    {
        intpx=bleg[x];
        bleg[x]=y;
        x=px;
    }
    returny;
}
voidUnion(inta,intb)
{
    a=Find(a),b=Find(b);
    bleg[b]=a;
}
intFinds(intx)
{
    inty=x;
    while(y!=blegs[y])
    y=blegs[y];
    while(x!=blegs[x])
    {
        intpx=blegs[x];
        blegs[x]=y;
        x=px;
    }
    returny;
}
voidUnions(inta,intb)
{
    a=Finds(a),b=Finds(b);
    blegs[a]=b;
}
voidtarjan(intv)
{
    st[++top]=v;
    while(top)
    {
        v=st[top];
        if(!vis[v])
        dfn[v]=low[v]=++num,vis[v]=1;
        ancestor[Find(v)]=v;
        inti;
        for(i=first[v];i!=-1;i=edge[i].next)
        {
            intu=edge[i].e;
            if(fids[ids[i]])
            continue;
            fids[ids[i]]=1;
            if(!vis[u])
            {
                fa[u].a=v,fa[u].b=i;
                break;
            }
            elseif(vis[u]==1)
            low[v]=min(low[v],dfn[u]);
        }
        if(i==-1 && top>1)
        {
            Union(st[top-1],v);
            low[st[top-1]]=min(low[st[top-1]],low[v]);
            if(low[v]>dfn[st[top-1]])
            {
                scc++;
                edges[ids[fa[v].b]]=1;
            }
        }
        if(i==-1)
        {
            vis[v]=2;
            top--;
            used[v]=1;
            for(i=first1[v];i!=-1;i=Tedge[i].next)
            if(used[Tedge[i].e] && !fids1[ids1[i]])
            {
                lca[ids1[i]]=ancestor[Find(Tedge[i].e)];
                fids1[ids1[i]]=1;
            }
        }
        else
        st[++top]=edge[i].e;
    }
}
intmain()
{
    intn,m,q,cas=0;
    while(scanf("%d%d",&n,&m),m+n)
    {
        cas++;
        memset(first,-1,sizeof(first));
        memset(first1,-1,sizeof(first1));
        memset(dfn,0,sizeof(dfn));
        memset(edges,0,sizeof(edges));
        memset(fids,0,sizeof(fids));
        memset(fids1,0,sizeof(fids1));
        memset(used,0,sizeof(used));
        memset(vis,0,sizeof(vis));
        inta,b,nume,number;
        number=nume=top=scc=num=0;
        for(inti=1;i<=n;i++)
        blegs[i]=fa[i].a=bleg[i]=i;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            ids[nume]=number;
            edge[nume].e=b,edge[nume].next=first[a],first[a]=nume++;
            ids[nume]=number++;
            edge[nume].e=a,edge[nume].next=first[b],first[b]=nume++;
        }
        number=nume=0;
        scanf("%d",&q);
        for(inti=0;i<q;i++)
        {
            scanf("%d%d",&a,&b);
            qurey[i].a=a,qurey[i].b=b;
            ids1[nume]=number;
            Tedge[nume].e=b,Tedge[nume].next=first1[a],first1[a]=nume++;
            ids1[nume]=number++;
            Tedge[nume].e=a,Tedge[nume].next=first1[b],first1[b]=nume++;
        }
        tarjan(1);
        printf("Case %d:n",cas);
        for(inti=0;i<q;i++)
        {
            if(scc!=0)
            {
                for(intk=qurey[i].a,j=Finds(fa[k].a);j!=Finds(qurey[i].a);k=j,j=Finds(fa[j].a))
                {
                    Unions(qurey[i].a,j);
                    if(edges[ids[fa[k].b]])
                    {
                        scc--;
                        edges[ids[fa[k].b]]=0;
                    }
                    if(j==Find(lca[i]))
                    break;
                }
                for(intk=qurey[i].b,j=Finds(fa[k].a);j!=Finds(qurey[i].b);k=j,j=Finds(fa[j].a))
                {
                    Unions(qurey[i].b,j);
                    if(edges[ids[fa[k].b]])
                    {
                        scc--;
                        edges[ids[fa[k].b]]=0;
                    }
                    if(j==Finds(lca[i]))
                    break;
                }
                Union(qurey[i].a,qurey[i].b);
            }
            printf("%dn",scc);
        }
        printf("n");
    }
    return0;
}
原创粉丝点击