图论中有一个基本的问题,那就是一个无向图的连通性判别问题,今天我们就来讨论这个问题,我们知道,在计算机中一张图可以有两种表示方法,一是邻接矩阵二是邻接表,其中的邻接矩阵表示方法,我们已经在课堂上介绍最小生成树问题时讨论过,今天我们就来讨论用邻接表表示的图的连通性问题。要求不能用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;
}