图的连通性问题-其他方法

图论中有一个基本的问题,那就是一个无向图的连通性判别问题,今天我们就来讨论这个问题,我们知道,在计算机中一张图可以有两种表示方法,一是邻接矩阵二是邻接表,其中的邻接矩阵表示方法,我们已经在课堂上介绍最小生成树问题时讨论过,今天我们就来讨论用邻接表表示的图的连通性问题。要求不能用DFS、BFS、并查集三种方法求解。

Input

本问题有多组测试数据,每组测试数据有两部分,第一部分只有一行,是两个正整数,分别表示图的节点数N(节点
编号从1到N,1<=N<=100)和图的边数E;第二部分共有E行,每行也是两个整数N1,N2(1<=N1,N2<=N),分
别表示N1和N2之间有一条边。

Output

对于每一组测试数据,输出只有一行,如果是连通图,那么输出“Yes”,否则输出“No”。

Sample Input

6 10
1 2
1 3
1 4
1 5
1 6
2 3
2 4
3 4
3 5
3 6
4 3
1 2
1 3
2 3

Sample Output

Yes
No
#include<bits/stdc++.h>
using namespace std;
const int MAXN=500005;
bool fir_in[MAXN];
int n,m,d,a1,b1,v[MAXN],u[MAXN],U[MAXN],V[MAXN],now;
char q[10];
struct tree
{
    int fa,ch[2],lazy;
} t[MAXN];
int stk[MAXN],top;
void pushdown(int root)
{
    if(t[root].lazy)
    {
        t[root].lazy=0;
        swap(t[root].ch[0],t[root].ch[1]);
        t[t[root].ch[0]].lazy^=1;
        t[t[root].ch[1]].lazy^=1;
    }
    return;
}
bool isroot(int root)
{
    return t[t[root].fa].ch[0]!=root&&t[t[root].fa].ch[1]!=root;
}
void rot(int root)
{
    int fa=t[root].fa;
    int gfa=t[fa].fa;
    int t1=(root!=t[fa].ch[0]);
    int t2=(fa!=t[gfa].ch[0]);
    int ch=t[root].ch[1^t1];
    if(!isroot(fa))t[gfa].ch[0^t2]=root;
    t[ch].fa=fa;
    t[root].fa=gfa;
    t[root].ch[1^t1]=fa;
    t[fa].fa=root;
    t[fa].ch[0^t1]=ch;
    return;
}
void splay(int root)
{
    stk[++top]=root;
    for(int i=root; !isroot(i); i=t[i].fa)
    {
        stk[++top]=t[i].fa;
    }
    while(top)
    {
        pushdown(stk[top--]);
    }
    while(!isroot(root))
    {
        int fa=t[root].fa;
        int gfa=t[fa].fa;
        if(!isroot(fa))
            root==t[fa].ch[0]^fa==t[gfa].ch[0]?rot(root):rot(fa);
        rot(root);
    }
    return;
}
void access(int root)
{
    int temp=0;
    while(root)
    {
        splay(root);
        t[root].ch[1]=temp;
        temp=root;
        root=t[root].fa;
    }
    return;
}
void makeroot(int root)
{
    access(root);
    splay(root);
    t[root].lazy^=1;
}
void link(int root1,int root2)
{
    makeroot(root1);
    t[root1].fa=root2;
}
void cut(int root1,int root2)
{
    makeroot(root1);
    access(root2);
    splay(root2);
    t[root2].ch[0]=t[root1].fa=0;
}
int findroot(int root)
{
    access(root);
    splay(root);
    int temp=root;
    while(t[temp].ch[0])temp=t[temp].ch[0];
    return temp;
}
int root_find_pre(int root)//必须是伸展根才能使用
{
    root=t[root].ch[0];
    while(t[root].ch[1])root=t[root].ch[1];
    return root;
}
bool has_edge(int root1,int root2)//可以优化成t[root2].ch[0]==root1&&t[t[root2].ch[0]].ch[1]==0;
{
    makeroot(root1);
    access(root2);
    splay(root2);
    return root_find_pre(root2)==root1;
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        memset(t,0,sizeof(tree)*(n+5));
        for(int i=1; i<=m; ++i)
        {
            scanf("%d %d",&a1,&b1);
            if(findroot(a1)!=findroot(b1))
            {
                link(a1,b1);
            }
        }
        makeroot(1);
        bool f=true;
        for(int i=1;i<=n;++i)
        {
            if(findroot(i)!=1)f=false;
        }
        printf("%s\n",f?"Yes":"No");
    }
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e17;
const int MAXN = 300000;
struct qnode {
  long long v;
  long long c;
  qnode(long long _v = 0, long long _c = 0) : v(_v), c(_c) {}
  bool operator<(const qnode &r) const {
      return c > r.c;
  }
};
struct Edge {
  long long v, cost, cost2;
  Edge(long long _v = 0, long long _cost = 0, long long _cost2 = 0) : v(_v), cost(_cost), cost2(_cost2) {}
};
vector<Edge> E[MAXN];
bool vis[MAXN];
long long dist[MAXN];
void Dijkstra(int n, int start) //点的编号从1开始
{
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; i++)
        dist[i] = INF;
    priority_queue<qnode> que;
    while (!que.empty())
        que.pop();
    dist[start] = 0;
    que.push(qnode(start, 0));
    qnode tmp;
    while (!que.empty()) {
        tmp = que.top();
        que.pop();
        int u = tmp.v;
        if (vis[u])
            continue;
        vis[u] = true;
        for (int i = 0; i < E[u].size(); i++) {
            long long v = E[tmp.v][i].v;
            long long cost = E[u][i].cost;
            if (!vis[v] && dist[v] > dist[u] + cost) {
                dist[v] = dist[u] + cost;
                que.push(qnode(v, dist[v]));
            }
        }
    }
}
void addedge(long long u, long long v, long long a, long long b) {
    E[u].push_back(Edge(v, a, b));
}
int main() {
    int T;

    int n;
    while(scanf("%d", &n)!=EOF) {
        int m;
        scanf("%d", &m);
        for (int i = 0; i <= MAXN; i++)
            if (!E[i].empty())
                E[i].clear();
        long long u, v, w, a, b;
        for (int i = 1; i <= m; i++) {
            scanf("%lld %lld", &u, &v);
            addedge(u, v, 1, 1);
            addedge(v, u, 1, 1);
        }
        Dijkstra(n, 1);
        int flag=0;
        for (int i = 1; i <= n; i++) {
            if(dist[i]==INF){
                flag=1;
                break;
            }
        }
        printf("%s\n",flag==0?"Yes":"No");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44061561/article/details/94449402