强化阶段 Day 22 算法笔记 10.3 图的遍历

本文深入探讨了图论中的关键算法,包括使用邻接矩阵和邻接表实现的BFS,以及寻找图中最大帮派首领的策略。通过对微博转发、城市争夺战和最深根节点问题的实例分析,阐述了如何运用这些算法解决实际问题。同时,文章还介绍了如何处理并消除图中的边,并通过层次编号优化搜索过程。
摘要由CSDN通过智能技术生成

目录

1.Head of a Gang

2.邻接矩阵版bfs

3.邻接表

4.带层号

5.Forwards on Weibo

6.Battle Over Cities

7.Deepest Root


1.Head of a Gang

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;

const int maxn=2005;
int g[maxn][maxn]={0},weight[maxn]={0};
map<string,int> stringtoint;
map<string,int> gang;
map<int,string> inttostring;
bool vis[maxn]={false};
int n,k;

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

void dfstrave(){
	for(int i=0;i<n;i++){
		if(vis[i]==false){
			int head=i,membernum=0,totalweight=0;
			dfs(i,head,membernum,totalweight);
			if(membernum>2&&totalweight>k){
				gang[inttostring[head]]=membernum;
			}
		}
	}
}

int numperson=0;
int change(string a){
	if(stringtoint.find(a)!=stringtoint.end()){
		return stringtoint[a];
	}else{
		stringtoint[a]=numperson;
		inttostring[numperson]=a;
		return numperson++;
	}
}

int main(){
	
	scanf("%d%d",&n,&k);
	string a,b;
	int w;
	for(int i=0;i<n;i++){
		cin>>a>>b>>w;
		int id1=change(a);
		int id2=change(b);
		g[id1][id2]+=w;
		g[id2][id1]+=w;
		weight[id1]+=w;
		weight[id2]+=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.邻接矩阵版bfs

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(u);
		}
	}
}

3.邻接表

const int maxv=100000;
int n,g[maxv][maxv];
bool inq[maxv]={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[v][u]!=inf){
				q.push(v);
				inq[v]=true;
			}
		}
	}
}

4.带层号

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

5.Forwards on Weibo

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;

const int maxv=1010;
struct node{
	int id;
	int layer;
};
vector<node> adj[maxv];
bool inq[maxv]={false};

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

int main(){
	
	int n,l;
	scanf("%d%d",&n,&l);
	int follownum,id;
	node user;
	for(int i=1;i<=n;i++){
		user.id=i;
		scanf("%d",&follownum);
		for(int j=0;j<follownum;j++){
			scanf("%d",&id);
			adj[id].push_back(user);
		}
	}
	
	int numquery;
	scanf("%d",&numquery);
	int s;
	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;
}

6.Battle Over Cities

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;

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

int father[maxn];
bool vis[maxn];

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 union(int a,int b){
	int fa=findfather(a);
	int fb=findfather(b);
	if(fa!=fb){
		father[fa]=fb;
	}
}

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



int main(){
	
	int n,m,k;
	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 current;
	for(int i=0;i<k;i++){
		scanf("%d",&current);
		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==current||v==current) continue;
				union(u,v);
			}
		}
		int block=0;
		for(int i=1;i<=n;i++){
			if(i==currnt) continue;
			int fa=findfather[i];
			if(vis[fa]==false){
				vis[fa]=true;
				block++;
			}
		}
		printf("%d\n",block-1);
	}
	
	return 0;
}
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;

const int maxn=1005;
vector<int> g[maxn];
bool vis[maxn];

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

7.Deepest Root

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;

const int maxn=10005;
int father[maxn];
vector<int> g[maxn];
bool isroot[maxn]={false};

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 x,int y){
	int fx=findfather(x);
	int fy=findfather(y);
	if(fx!=fy){
		father[fx]=fy;
	}
}

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);
	for(int i=0;i<n-1;i++){
		int a,b;
		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]);
			}
		}
	}
	
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值