51nod 1076 关于环

判断无向图中两个点是否存在两条”不相交”即完全没有重合边的路径
绝望了很久,然后想到环这种东西,如果一个图中,有点的入度是1,那么他肯定不能和任何点有这种路径,那么把这种点剥离完之后,那个”环”就一定每个都满足.
判断森林情况.

#include <iostream>
#include <vector>
#include <set>
#include <queue>
using namespace std;
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
typedef long long LL;
const int MAXN = 5e5 + 17;
const int MOD = 1e9 + 7;
vector<int > G[MAXN];
int ind[MAXN],vis[MAXN],bel[MAXN];
void dfs(int p,int x)
{
    vis[p] = 1;
    bel[p] = x;
    for(auto i : G[p])
        if(!vis[i]) dfs(i,x);
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
    int m,n;
    cin>>m>>n;
    set<pair<int,int > > exi;
    for(size_t i = 0; i < n; i++)
    {
        int u,v;
        cin>>u>>v;
        u--;v--;
        if(u>v) swap(u,v);
        if(exi.find({u,v})!=exi.end()) continue;
        exi.insert({u,v});
        G[u].push_back(v);
        G[v].push_back(u);
        ind[u]++,ind[v]++;
    }
    int dap = 0;
    for(size_t i = 0; i < m; i++)
    {
        if(!vis[i])
        {
            dfs(i,dap);
            dap++;
        }
    }

    queue<int > que;
    set<int > s;
    for(size_t i = 0; i < m; i++)
        if(ind[i]==1)
            que.push(i);
    while(!que.empty())
    {
        int u = que.front();
        que.pop();
        s.insert(u);
        // debug(u);
        for(auto i : G[u])
        {
            // debug(i);
            ind[i]--;
            if(ind[i]==1)
                que.push(i);
        }
    }
    // debug(ind[5]);
    // debug(ind[10]);
    int q;
    cin>>q;
    while(q--)
    {
        int u,v;
        cin>>u>>v;
        u--,v--;
        if(bel[u]!=bel[v]||s.find(u)!=s.end()||s.find(v)!=s.end())
        {
            cout<<"No"<<endl;
        }
        else
            cout<<"Yes"<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37802215/article/details/80993498