zoukankan      html  css  js  c++  java
  • 2017省夏令营Day8

    题解:出题人丧心病狂~ 对于这道题,我们对每一个内应节点bfs,并用并查集维护,如果s和t联通,输出答案并break。

    PS几个小细节:①对于每个内应dis=0,为了保证不会对答案产生影响,我们在每2个节点中插入一个新的节点即可;

    ②因为加入新节点,数组要开大些,否则会炸。

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define Max 2020304
     5 using namespace std;
     6 int n,m,k,s,t,dis[Max],fa[Max],hd,tl,q[Max*2];
     7 int tot,to[Max],next[Max],head[Max];
     8 bool flag,vis[Max];
     9 void add(int x,int y){
    10     to[++tot]=y; next[tot]=head[x]; head[x]=tot;
    11     to[++tot]=x; next[tot]=head[y]; head[y]=tot;
    12 }
    13 int find(int x){
    14     if(fa[x]==0) return x;
    15     return fa[x]=find(fa[x]);
    16 }
    17 void prework(){
    18     flag=true; hd=0; tl=k;
    19     memset(fa,0,sizeof(fa));
    20     memset(vis,0,sizeof(vis));
    21     memset(dis,-1,sizeof(-1));
    22     for(int i=1;i<=k;i++) vis[q[i]]=true,dis[q[i]]=0;
    23 }
    24 void bfs(){
    25     prework();
    26     while(hd<tl){
    27         int vex=q[++hd]; if(!flag) break;
    28         for(int i=head[vex];i;i=next[i]){
    29             if(!flag) break;
    30             int u=find(vex),v=find(to[i]);
    31             if(u!=v) fa[u]=v;
    32             if(find(s)==find(t)){printf("%d
    ",dis[vex]+1); flag=false; break;}
    33             if(!vis[to[i]]){
    34                 dis[to[i]]=dis[vex]+1;
    35                 vis[q[++tl]=to[i]]=true;
    36             }
    37         }
    38     }
    39     if(flag) printf("-1
    ");
    40 }
    41 int main()
    42 {
    43     freopen("masquerade.in","r",stdin);
    44     freopen("masquerade.out","w",stdout);
    45     int T; scanf("%d",&T);
    46     while(T--){
    47         memset(head,tot=0,sizeof(head));
    48         memset(to,0,sizeof(to));
    49         memset(next,0,sizeof(next));
    50         scanf("%d%d%d",&n,&m,&k);
    51         for(int i=1;i<=k;i++) scanf("%d",&q[i]);
    52         int now=n;
    53         for(int i=1;i<=m;i++){
    54             int x,y; scanf("%d%d",&x,&y);
    55             add(x,++now); add(now,y);
    56         }
    57         scanf("%d%d",&s,&t); q[++k]=t;
    58         bfs();
    59     }
    60 }

    ---------------------------------------------------------------华丽的分割线------------------------------------------------------------------------

    ---------------------------------------------------------------华丽的分割线------------------------------------------------------------------------

  • 相关阅读:
    c#参数传递几点小结
    c#线程初探(二)
    c#线程初探(一)
    c#:浅克隆和深克隆,序列化和反序列化
    c#冒泡、快速、选择和插入排序算法的项目应用
    c#运算符几点小结
    文件操作(无代码)
    不仅仅C#缺点(永远未完)
    《道德经》程序员版第五章
    《道德经》程序员版第四章
  • 原文地址:https://www.cnblogs.com/Beginner-/p/7231415.html
Copyright © 2011-2022 走看看