1 条题解

  • 0
    @ 2025-5-5 0:48:09

    🔍 解题思路

    这里提供一种更简洁的写法,不过思想大同小异。

    主要分两步。

    首先起点bfs一波,看i是不是必经点。

    然后不用再搜索了,因为第一张子图的点集已确定,第二张子图的也就显而易见,遍历这个点集,假如有连向起点子图的就不满足。

    //By: Sirius_Ren
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    int tot=1,first[51],cnt,v[101],nxt[101],n,vis[51],ansx=0,ansy=0,j,k;
    queue<int> p,q,r;
    void add(int x,int y){v[tot]=y,nxt[tot]=first[x],first[x]=tot++;}
    int main()
    {
        memset(first,-1,sizeof(first));
        for(cnt=0;~n;cnt++)
            while(scanf("%d",&n)&&n>=0)add(cnt,n);
        cnt--;
        for(int i=1;i<cnt;i++){
            memset(vis,0,sizeof(vis));
            q.push(0);vis[i]=1;
            while(!q.empty()){
                int t=q.front();q.pop();
                vis[t]=1;
                for(int l=first[t];~l;l=nxt[l])
                    if(!vis[v[l]])q.push(v[l]);
            }
            if(!vis[cnt]){
                ansx++,p.push(i);
                for(j=0;j<=cnt;j++)
                    if(!vis[j]||j==i)
                        for(k=first[j];~k;k=nxt[k])
                            if(vis[v[k]]&&v[k]!=i)goto end;
                ansy++,r.push(i);
                end:;
            }
        }
        printf("%d",ansx);
        while(!p.empty())printf(" %d",p.front()),p.pop();
        printf("\n");
        printf("%d",ansy);
        while(!r.empty())printf(" %d",r.front()),r.pop();
    }
    • 1

    信息

    ID
    173
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者