这大周主要是讲图论和刷题。图论讲了好多啊(我感觉)。讲完了吧·······所以整本黑皮书就只剩数论了。感觉图论有好多东西啊。慢慢聊······
遍历——
(所有 的都拿犯罪团伙作为题目。)
邻接矩阵存储+深搜
#include<bits/stdc++.h>
using namespace std;
int a[1100][1100];
bool vis[1100];
int xx,yy,n,m,ans=0;
void dfs(int k)//深搜开始
{
for (int j=1;j<=n;j++)
if (a[k][j]&&!vis[j])//如果两边直接右边且j点未被访问
{
vis[j]=true;//标记为访问过
dfs(j);//继续搜索
}
}
int main()
{
cin>>n>>m;
for (int i=1;i<=m;i++)
{
cin>>xx>>yy;
a[xx][yy]=1;
a[yy][xx]=1;
}//输入,存储。因为这里是没有权值的图,所以不用判断边的长短。
for (int i=1;i<=n;i++)
if (!vis[i])//如果该点没有被访问
{
ans++;//组织数++
dfs(i);//搜索i点所在组织的人的编号
}
cout<<ans<<endl;//输出共有几个组织
return 0;
}
邻接表+深搜
#include<bits/stdc++.h>
using namespace std;
int n,m,ans=0;
int lin[50500];
int len=0;
bool vis[50500]={false};
struct edge
{
int y,v,next;
}e[50500];
void insert(int xx,int yy,int vv)//输入边表
{
e[++len].next=lin[xx];
lin[xx]=len;
e[len].y=yy;
e[len].v=vv;
}
void dfs(int k)//搜索开始,思路与上面大致相同
{
for(int j=lin[k];j;j=e[j].next)
if (!vis[e[j].y])
{
vis[e[j].y]=true;
dfs(e[j].y);
}
}
int main()
{
cin>>n>>m;
memset(e,0,sizeof(e));
memset(lin,0,sizeof(lin));
for (int i=1;i<=m;i++)
{
int xx,yy,vv;
cin>>xx>>yy;
vv=1;
insert(xx,yy,vv);
insert(yy,xx,vv);
}
for (int i=1;i<=n;i++)
if (!vis[i])
{
ans++;
dfs(i);
}
cout<<ans<<endl;
return 0;
}
邻接表+广搜
#include<bits/stdc++.h>
using namespace std;
int n,m,ans=0,q[400100]={};
int len=0;
struct edge
{
int y,next,v;
}e[400100];
int lin[400100];
bool vis[400100]={false};
void insert(int xx,int yy,int vv)
{
e[++len].next=lin[xx];
lin[xx]=len;
e[len].y=yy;
e[len].v=vv;
}
void bfs(int k)
{
int head=0,tail=1;
q[1]=k;
while(head++<tail)
{
for (int j=lin[q[head]];j;j=e[j].next)
if (!vis[e[j].y])
{
vis[e[j].y]=1;
q[++tail]=e[j].y;
}
}
}
int main()
{
cin>>n>>m;
memset(lin,0,sizeof(lin));
memset(e,0,sizeof(e));
for (int i=1;i<=m;i++)
{
int xx,yy,vv;
cin>>xx>>yy;
vv=1;
insert(xx,yy,vv);
insert(yy,xx,vv);
}
for (int i=1;i<=n;i++)
if (!vis[i])
{
bfs(i);
ans++;
}
cout<<ans;
}