题解 洛谷P2189 【小Z的传感器】

这题就是考察什么时候建边,貌似和搜索没有半毛钱关系\(qwq\)

首先没有传感器的房间是可以随便走来走去的,因为我们不用考虑顺序。于是就考虑先把这些点的相互的边给建起来。

接下来分析一波,对于第\(i\)个得到信息的房间,我们绝对不能在此之前经过第\(i+1\) ~ \(k\)的房间。所以,除了这些房间,我们将其余所有连边,再判断第\(i-1\)个房间能否到\(i\)房间即可。

因为只要判断房间之间的连通性,用冰茶机来维护是再好不过了。

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    register int s=0,f=1;
    register char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f*=-1;ch=getchar();}
    while(isdigit(ch))s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
    return s*f;
}
const int max_n=100000+5;
int a[max_n],par[max_n],vis[max_n];//par表示祖先,vis表示哪些点可以连 
vector<int>Next[max_n];
int find(int x){
    if(x==par[x])return x;//找到祖先 
    return par[x]=find(par[x]);//路径压缩 
}
void merge(int x,int y){
    x=find(x),y=find(y);//找祖先 
    if(x==y)return;//同一个祖先?大雾 
    par[y]=x;
}
void add(int x){//找所有和x联通并可以连边的点 
    for(int i=0;i<Next[x].size();i++){
        if(vis[Next[x][i]]==0)merge(x,Next[x][i]);//可以连就连 
    }
}
int main(){
    int n=read(),m=read(),k=read(),T=read();
    while(m--){
        int x=read(),y=read();
        Next[x].push_back(y);
        Next[y].push_back(x);
    }
    while(T--){
        for(int i=1;i<=n;i++)par[i]=i;//冰茶机的初始化qwq 
        for(int i=1;i<=k;i++){
            a[i]=read(),vis[a[i]]=1;//标记这个点不能连 
        }
        for(int i=1;i<=n;i++){
            if(vis[i]==0)add(i);
        }
        vis[a[1]]=0,add(a[1]);
        for(int i=2;i<=k;i++){
            vis[a[i]]=0,add(a[i]);//连上这个点 
            if(find(a[i])!=find(a[i-1])){puts("No");break;}//连不同就凉了 
            if(i==k)puts("Yes"); 
        }
    }
    return 0;
}

于是\(50\)行就切掉了这道紫题真香

上一篇:hive的分区


下一篇:CF650C Table Compression