zoukankan      html  css  js  c++  java
  • P3144 [USACO16OPEN]关闭农场Closing the Farm

    https://www.luogu.org/problem/show?pid=3144#sub

    这里写图片描述
    这里写图片描述

    分析:按顺序去掉点后查询图是否还是联通的,那么我们就可以按照删除的顺序倒着加点。
    在加某个点之前判断图是否是联通的,即按顺序去掉这个点后图是否是联通的。
    具体的处理方法:根据输出要求,我们可以先把最后一个去掉的点加进图中;然后在倒着放入其它点
    (第i个点)之前先判断当前图是否是联通的,将答案存入ans[i+1]中,当i为0时,只判断图是否是联通的,
    然后break掉就可以了。

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    vector <int> to[3009];
    int n,m,p[3009],f[3009];
    string ans[3009];
    bool vis[3009];
    vector <int> q;
    int find(int x)
    {
        return x==f[x]?x:f[x]=find(f[x]);
    }
    void add(int x)
    {
        for(int i=0;i<to[x].size();i++)
         if(vis[to[x][i]]) f[find(x)]=find(to[x][i]);
    
        q.push_back(x);
        vis[x]=1;
    }
    bool judge()
    {
        if(!q.size()) return true;
        else{
            int fa=find(q[0]);
            for(int i=1;i<q.size();i++)
            {
                int k=q[i];
                if(find(k)!=fa) 
                return false;
            }
        }
        return true;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) f[i]=i;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            to[x].push_back(y);
            to[y].push_back(x);
        }
        for(int i=1;i<=n;i++)
         scanf("%d",&p[i]);
        add(p[n]);
        for(int i=n-1;i>=0;i--)
        {
            if(judge()) ans[i+1]="YES";
            else ans[i+1]="NO";
    
            if(i==0) break;
    
            add(p[i]);
        }
        for(int i=1;i<=n;i++)
         cout<<ans[i]<<endl;
        return 0;
    }
  • 相关阅读:
    ES6 解构
    flutter
    selenium
    selenium
    python
    selenium
    selenium
    selenium
    selenium
    selenium- SMTP发送邮件
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587870.html
Copyright © 2011-2022 走看看