NOIP模拟测试8「匹配·回家」

匹配

哈希能A

水到爆炸

回家

事实上我做过一个原题,甚至比这个回家难的多,而且那个题多组询问必经点

然后我做一组询问就打炸了

大约就是删了很多东西,然后自己想的太简单了

直接统计了割点,懒得打lca和树上差分,懒得打dfs,偷懒让我付出很大代价

最后只有10,

打代码一定不能偷懒,一定不能偷懒

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 810000
ll dfn[A],low[A],ver[A],nxt[A],head[A],s[A],fa[A],belong[A],kx[A];
ll Head[A],Nxt[A],Ver[A],To[A],vst[A];
ll tot=0,tot2=0,num=0,n,m,t,root;
vector<ll> dcc[A],ans;
bool cut[A];
void add(ll x,ll y){
    nxt[++tot]=head[x],head[x]=tot,ver[tot]=y;
}
void Add(ll x,ll y){
    Nxt[++tot2]=Head[x],Head[x]=tot2,Ver[tot2]=y;
}
inline ll read(){
    ll f=1,x=0;char c=getchar();
    while(!isdigit(c)){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(isdigit(c)){
        x=(x<<1)+(x<<3)+(c-'0');
        c=getchar();
    }
    return f*x;
}
void tarjan(ll x)
{
    ll flag=0;
    dfn[x]=low[x]=++tot;
    s[++s[0]]=x;
    for(ll i=head[x];i;i=nxt[i])
    {
        ll y=ver[i];
        if(!dfn[y])
        {
            tarjan(y);
            low[x]=min(low[x],low[y]);
            if(low[y]>=dfn[x])
            {
                flag++;
                num++;
                if(flag>1||x!=root)cut[x]=1;
                while(s[0])
                {
                    ll p=s[s[0]--];
                    dcc[num].push_back(p);
                    if(p==y)break;
                }
                dcc[num].push_back(x);
            }
        }
        else low[x]=min(low[x],dfn[y]);
    }
}
void dfs(ll x)
{
    if(x==belong[n])return ;
    vst[x]=1;
    for(ll i=Head[x];i;i=Nxt[i])
    {
        ll y=Ver[i];
        if(vst[y])continue;
        fa[y]=x;
        dfs(y);
    }
    return ;
}
void re(){
    num=0,tot=0;ans.clear();tot2=0;
    for(ll i=0;i<=800000;i++)    
        dcc[i].clear();
    memset(nxt,0,sizeof(nxt));
    memset(Head,0,sizeof(Head));
    memset(Nxt,0,sizeof(Nxt));
    memset(fa,0,sizeof(fa));
    memset(vst,0,sizeof(vst));
    memset(head,0,sizeof(head));
    memset(ver,0,sizeof(ver));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(cut,0,sizeof(cut));
    memset(kx,0,sizeof(kx));
}
int main()
{
    t=read();
    while(t--){
        re();
        n=read(),m=read();
        for(ll i=1;i<=m;i++){
            ll x=read(),y=read();
            add(x,y);
            add(y,x);
        }
        for(ll i=1;i<=n;i++)
            if(!dfn[i]) root=i,tarjan(i);
        ll nu=num;
        for(ll i=1;i<=n;i++)
            if(cut[i])belong[i]=++nu,kx[nu]=i;
        for(ll i=1;i<=num;i++)
            for(ll j=0;j<dcc[i].size();j++){
                ll x=dcc[i][j];
                if(cut[x]) Add(belong[x],i),Add(i,belong[x]);
                else belong[x]=i;
            }
/*        for(ll i=1;i<=n;i++){
            cout<<"belong="<<belong[i]<<endl;
        }
*/        dfs(belong[1]);
        ll x=fa[belong[n]];
        while(x!=belong[1]){
            if(x==0) break;
            if(x>num) ans.push_back(kx[x]);
            x=fa[x];
        }
        printf("%lld\n",1ll*ans.size());
        sort(ans.begin(),ans.end());
        for(ll i=0;i<ans.size();i++)
            printf("%lld ",ans[i]);
        cout<<endl;
    }
}

 

posted @ 2019-07-26 08:48  znsbc  阅读(160)  评论(0编辑  收藏  举报