Day 46 算法笔记之提高篇(4)10.3 图的遍历

目录

1.深度优先搜索

1.1邻接矩阵

2.2邻接表

2.3 Head of a Gang

2.广度优先搜索

2.1邻接矩阵

2.2邻接表

2.3层号版

2.4Forwards on Weibo

3.Battle Over Cities

3.1图

3.2并查集

4.Deepest Root


1.深度优先搜索

1.1邻接矩阵

const int maxv = 1000;
const int inf = 100000000;

int n,g[maxv][maxv];
bool vis[maxv] = {false};

void dfs(int u,int depth){
	vis[u] = true;
	for(int v=0;v<n;v++){
		if(vis[v]==false&&g[u][v]!=inf){
			dfs(v,depth+1);
		}
	}
}

void dfstrave(){
	for(int u=0;u<n;u++){
		if(vis[u]==false){
			dfs(u,1);
		}
	}
}

2.2邻接表

const int maxv = 1000;
const int inf = 100000000;

vector<int> adj[maxv];
int n;
bool vis[maxv] = {false};

void dfs(int u,int depth){
	vis[u] = true;
	for(int i=0;i<adj[u].size();i++){
		int v = adj[u][i];
		if(vis[v]==false){
			dfs(v,depth+1);
		}
	}
}

void dfstrave(){
	for(int u=0;u<n;u++){
		if(vis[u]==false){
			dfs(u,1);
		}
	}
}

2.3 Head of a Gang

#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<string>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxn = 2010;
const int inf = 100000000;

map<int,string> inttostring;
map<string,int> stringtoint;
map<string,int> gang;

int g[maxn][maxn] = {0},weight[maxn] = {0};
int n,k,numperson;
bool vis[maxn] = {false};

void dfs(int nowvisit,int& head,int& nummember,int& totalvalue){
	nummember++;
	vis[nowvisit] = true;
	if(weight[nowvisit]>weight[head]){
		head = nowvisit;
	}
	for(int i=0;i<numperson;i++){
		if(g[nowvisit][i]>0){
			totalvalue += g[nowvisit][i];
			g[nowvisit][i]=g[i][nowvisit]=0;
			if(vis[i]==false){
				dfs(i,head,nummember,totalvalue);
			}
		}
	}
}

void dfstrave(){
	for(int i=0;i<numperson;i++){
		if(vis[i]==false){
			int head = i,nummember=0,totalvalue=0;
			dfs(i,head,nummember,totalvalue);
			if(nummember>2&&totalvalue>k){
				gang[inttostring[head]] = nummember;
			}
		}
	}
}
int change(string str){
	if(stringtoint.find(str)!=stringtoint.end()){
		return stringtoint[str];
	}else{
		stringtoint[str] = numperson;
		inttostring[numperson] = str;
		return numperson++;
	}
}

int main(){
	int w;
	string str1,str2;
	cin>>n>>k;
	for(int i=0;i<n;i++){
		cin>>str1>>str2>>w;
		int id1=change(str1);
		int id2=change(str2);
		weight[id1]+=w;
		weight[id2]+=w;
		g[id1][id2]+=w;
		g[id2][id1]+=w;
	}
	dfstrave();
	cout<<gang.size()<<endl;
	map<string,int>::iterator it;
	for(it=gang.begin();it!=gang.end();it++){
		cout<<it->first<<" "<<it->second<<endl;
	}
	
	
	return 0;
}

2.广度优先搜索

2.1邻接矩阵

const int maxn = 2010;
const int inf = 100000000;

int n,g[maxn][maxn];
bool inq[maxn] = {false};

void bfs(int u){
	queue<int> q;
	q.push(u);
	inq[u] = true;
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int v=0;v<n;v++){
			if(inq[v]==false&&g[u][v]!=inf){
				q.push(v);
				inq[v] = true;
			}
		}
	}
}

void bfstrave(){
	for(int u=0;u<n;u++){
		if(inq[u]==false){
			bfs(q);
		}
	}
}

2.2邻接表

const int maxn = 2010;
const int inf = 100000000;

vector<int> adj[maxn];
int n;
bool inq[maxn] = {false};

void bfs(int u){
	queue<int> q;
	q.push(u);
	inq[u] = true;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=0;i<adj[u].size();i++){
			int v = adj[u][i];
			if(inq[v]==false){
				q.push(v);
				inq[v] = true;
			}
		}
	}
}

void bfstrave(){
	for(int u=0;u<n;u++){
		if(inq[u]==false){
			bfs(q);
		}
	}
}

2.3层号版

const int maxn = 2010;
const int inf = 100000000;

struct node{
	int v;
	int layer;
};
vector<node> adj[maxn];

void bfs(int s){
	queue<node> q;
	node start;
	start.v=s;
	start.layer=0;
	q.push(start);
	inq[start.v] = true;
	while(!q.empty()){
		node topnode = q.front();
		q.pop();
		int u = topnode.v;
		for(int i=0;i<adj[u].size();i++){
			node next = adj[u][i];
			next.layer = topnode.layer+1;
			if(inq[next.v]==false){
				q.push(next);
				inq[next.v] = true;
			}
		}
	}
}

2.4Forwards on Weibo

#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxv = 2010;
const int inf = 100000000;

struct node{
	int id;
	int layer;
};

vector<node> adj[maxv];
bool inq[maxv] = {false};

int bfs(int s,int l){
	int numforward = 0;
	queue<node> q;
	node start;
	start.id = s;
	start.layer = 0;
	q.push(start);
	inq[start.id] = true;
	while(!q.empty()){
		node topnode = q.front();
		q.pop();
		int u = topnode.id;
		for(int i=0;i<adj[u].size();i++){
			node next = adj[u][i];
			next.layer = topnode.layer+1;
			if(inq[next.id]==false&&next.layer<=l){
				q.push(next);
				inq[next.id] = true;
				numforward++;
			}
		}
	}
	return numforward;
}



int main(){
	
	node user;
	int n,l,numfollow,idfollow;
	scanf("%d%d",&n,&l);
	for(int i=1;i<=n;i++){
		user.id=i;
		scanf("%d",&numfollow);
		for(int j=0;j<numfollow;j++){
			scanf("%d",&idfollow);
			adj[idfollow].push_back(user);
		}
	}
	
	int numquery,s;
	scanf("%d",&numquery);
	for(int i=0;i<numquery;i++){
		memset(inq,false,sizeof(inq));
		scanf("%d",&s);
		int numforward = bfs(s,l);
		printf("%d\n",numforward);
	}
	
	
	return 0;
}

3.Battle Over Cities

3.1图

#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;

const int N = 1111;
vector<int> g[N];
bool vis[N];

int currentpoint;
void dfs(int v){
	if(v==currentpoint) return;
	vis[v] = true;
	for(int i=0;i<g[v].size();i++){
		if(vis[g[v][i]]==false){
			dfs(g[v][i]);
		}
	}
}

int n,m,k;
int main(){
	scanf("%d%d%d",&n,&m,&k);
	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);
	}
	for(int query=0;query<k;query++){
		scanf("%d",&currentpoint);
		memset(vis,false,sizeof(vis));
		int block=0;
		for(int i=1;i<=n;i++){
			if(i!=currentpoint&&vis[i]==false){
				dfs(i);
				block++;
			}
		}
		printf("%d\n",block-1);
	}
	return 0;
}

3.2并查集

#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;

const int N = 1111;
vector<int> g[N];

int father[N];
bool vis[N];

int findfather(int x){
	int a = x;
	while(x!=father[x]){
		x = father[x];
	}
	while(a!=father[a]){
		int z = a;
		a = father[a];
		father[z] = x;
	}
	return x;
}

void unions(int a,int b){
	int faa = findfather(a);
	int fab = findfather(b);
	if(faa!=fab){
		father[faa] = fab;
	}
}

void init(){
	for(int i=1;i<N;i++){
		father[i] = i;
		vis[i] = false;
	}
}

int n,m,k;

int main(){
	
	scanf("%d%d%d",&n,&m,&k);
	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);
	}
	
	int currentpoint;
	for(int query=0;query<k;query++){
		scanf("%d",&currentpoint);
		init();
		
		for(int i=1;i<=n;i++){
			for(int j=0;j<g[i].size();j++){
				int u = i, v = g[i][j];
				if(u==currentpoint||v==currentpoint) continue;
				unions(u,v);
			}
		}
		
		int block=0;
		for(int i=1;i<=n;i++){
			if(i==currentpoint) continue;
			int fa_i = findfather(i);
			if(vis[fa_i]==false){
				block++;
				vis[fa_i] = true;
			}
		}
		printf("%d\n",block-1);
	}
	
	return 0;
}

4.Deepest Root

#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;

const int N = 100010;
vector<int> g[N];

bool isroot[N];
int father[N];
int findfather(int x){
	int a= x;
	while(x!=father[x]){
		x = father[x];
	}
	while(a!=father[a]){
		int z = a;
		a = father[a];
		father[z] = x;
	}
	return x;
}

void unions(int a,int b){
	int faa= findfather(a);
	int fab= findfather(b);
	if(faa!=fab){
		father[faa] = fab;
	}
}

void init(int n){
	for(int i=1;i<=n;i++){
		father[i] = i;
	}
}

int calblock(int n){
	int block = 0;
	for(int i=1;i<=n;i++){
		isroot[findfather(i)]=true;
	}
	for(int i=1;i<=n;i++){
		block+=isroot[i];
	}
	return block;
}

int maxh=0;
vector<int> temp,ans;

void dfs(int u,int height,int pre){
	if(height>maxh){
		temp.clear();
		temp.push_back(u);
		maxh = height;
	}else if(height==maxh){
		temp.push_back(u);
	}
	for(int i=0;i<g[u].size();i++){
		if(g[u][i]==pre) continue;
		dfs(g[u][i],height+1,u);
	}
}

int main(){
	int n;
	scanf("%d",&n);
	init(n);
	int a,b;
	for(int i=1;i<n;i++){
		scanf("%d%d",&a,&b);
		g[a].push_back(b);
		g[b].push_back(a);
		unions(a,b);
	}
	int block = calblock(n);
	if(block!=1){
		printf("Error: %d components\n",block);
	}else{
		dfs(1,1,-1);
		ans = temp;
		dfs(ans[0],1,-1);
		for(int i=0;i<temp.size();i++){
			ans.push_back(temp[i]);
		}
		sort(ans.begin(),ans.end());
		printf("%d\n",ans[0]);
		for(int i=1;i<ans.size();i++){
			if(ans[i]!=ans[i-1]){
				printf("%d\n",ans[i]);
			}
		}
	}
}

おすすめ

転載: blog.csdn.net/aixiaoxiao13/article/details/121592036