自己的DFS,样例没过,果然还是菜
#include <iostream>
#include<cstdio>
#define n 100
using namespace std;
int v,s;
//int flag[n];
int DFS(int G[][n],int s )
{
int count = 0;
int vis[n] = { 0 };
vis[s] = 1;
/*遍历所有节点*/
for (int i = 0; i < v; i++)
{
if (vis[s] == 0 && G[s][i] == 1)
count++;
}
if (count == v)
return 1;
else
return 0;
}
int main()
{
int sum = 0;
scanf("%d%d", &v, &s);
int G[n][n] = { 0 };
for (int i = 0; i < s; i++)
{
int ti, tj;
scanf("%d%d", &ti, &tj);
G[ti][tj] = 1;
}
//DFS
for (int i = 0; i < v; i++)
{
int t;
t=DFS(G, i);
sum += t;
}
if (sum == v)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
我的想法是从某一点出发开始深搜,只需要判断最后count的值是否为节点数,小于是不连通的,相等是连通的。
某DFS正确写法
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int way[1010][1010];
int visited[1010];
void DFS(int x, int n)
{
int i;
visited[x] = 1;
for (i = 1; i <= n; i++)
{
if (way[x][i] == 1 && visited[i] == 0)
{
DFS(i, n);
}
}
}
int main()
{
int i, n, m, x, y;
scanf("%d %d", &n, &m);
memset(way, 0, sizeof(way));
memset(visited, 0, sizeof(visited));
for (i = 0; i < m; i++)
{
scanf("%d %d", &x, &y);
way[x][y] = 1;
way[y][x] = 1;
}
DFS(1, n);
int flag = 0;
for (i = 1; i <= n; i++)
{
if (visited[i] == 0)
flag = 1;
}
if (flag == 1)
printf("NO\n");
else
printf("YES\n");
return 0;
}
来一块块分析:
首先DFS部分:非常正规,但是把for循环的条件改成从0-n-1答案错误
void DFS(int x, int n)
{
int i;
visited[x] = 1;
for (i = 1; i <=n; i++)
{
if (way[x][i] == 1 && visited[i] == 0)
{
DFS(i, n);
}
}
}
主函数部分:
int main()
{
int i, n, m, x, y;
scanf("%d %d", &n, &m);
memset(way, 0, sizeof(way));
memset(visited, 0, sizeof(visited));
for (i = 0; i < m; i++)
{
scanf("%d %d", &x, &y);
way[x][y] = 1;
way[y][x] = 1;
}
//问题1:为什么从1开始?
DFS(1, n);
int flag = 0;
//这里仍不能改成0-n-1;
for (i = 1; i <= n; i++)
{
if (visited[i] == 0)
flag = 1;
}
if (flag == 1)
printf("NO\n");
else
printf("YES\n");
return 0;
}
BFS的解决办法
我。。搬的,现在分析分析
知识点:
1Vector:
clear// 清除的使用
(
-
vector::clear()函数的作用是清空容器中的内容,但如果是指针对象的话,并不能清空其内容,必须要像以下方法一样才能达到清空指针对象的内容,但并不回收内存
vector xx;
for(int it=0;it!=xx.size();++it)
{
xx.clear();
} -
vector::erase()用于清空容器中的内容以及释放内存,并返回指向删除元素的下一个元素的迭代器。
-
begin函数:
功能:返回一个当前vector容器中起始元素的迭代器。
end函数:
功能:返回一个当前vector容器中末尾元素的迭代器。
push_bach函数:
·功能:在容器的尾端插入一个数据
4 memset
memset函数初始化int数组时还可以初始化为-1和0.true和false等价于0
2bool:是C++的关键字,一种数据类型,1.bool类型一般用一个字节存储,int根据平台不同,大小不同。一般在结构体中,bool只是二值的,用一个字节有点浪费空间,会使bool只占一位.类型转换,一个算术,枚举,指针,指向成员的右值,可以转换为bool。零,null pointer, null member pointer 可以转为false,其它的是true -
true可以提升为1,false可以提升为2
#include
#include
#include //容器
#include
#include //算法
#include //队列using namespace std;
const int MAXN=1000002;
vector g[MAXN];
bool vis[MAXN];
int n,m;
void bfs(int s)
{
//用队列广搜
queue q;
q.push(s);
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=true;
for(int i=0;i<g[x].size();++i)
{
if(vis[g[x][i]])
g[x].erase(g[x].begin()+i);
//删除图中已经遍历过的点,可提高遍历速度
else
q.push(g[x][i]);
}
}
}bool judge() { //判断是否所有点已被遍历过 for(int i=1;i<=n;++i) if(!vis[i]) return false; return true; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { g[i].clear(); } for(int i=0;i<m;++i) { int a,b; scanf("%d%d",&a,&b); g[a].push_back(b); //无向图转化为有向图,正反两次存入连接表。 g[b].push_back(a); } memset(vis,false,sizeof(vis)); bfs(1); if(judge()) printf("YES\n"); else printf("NO\n"); } return 0; }
并查集
#include<stdio.h>
int map[1005];
int n,m;
int find(int i)
{
return map[i]==i?i:find(map[i]);
}
void init()
{
for(int i=0;i<n;i++)
map[i]=i;
}
int main()
{
scanf("%d%d",&n,&m);
if(n==0) break;
init();
int a,b;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
a--;b--;
map[find(a)]=map[find(b)];
}
int cnt=0;
for(int i=0;i<n;i++)
{
if(map[i]==i)
cnt++;
}
if(cnt==1)
printf("YES\n");
else
printf("NO\n");
return 0;
}
https://blog.csdn.net/u013546077/article/details/64509038
明天在分析,要阵亡了,终于要迎来大一第一个寒假,哈哈