Fork me on GitHub

图论模板

[TOC]

存图

//邻接矩阵
a[x][y]=a[y][x]=z;
//vecot存图
const int N=1e5+10;
struct Edge{
	int v,w;
};
vector<Edge> G[N]; 

Edge make_Edge(int v,int w){
	Edge cur;
	cur.v=v;cur.w=w;
	return cur;
}

void addedge(int u,int v,int w){
	G[u].push_back(make_Edge(v,w));
	G[v].push_back(make_Edge(u,w));
}

//邻接表(链式前向星)
void add(int x,int y,int z){
	ver[++tot]=y;edge[tot]=z;next[tot]=head[x];head[x]=tot;
}

图的遍历

const int N=1e5+10;
vector<int> G[N];
int vis[N];
queue<int> q;
//存边
void addedge(int u,int v){
	G[u].push_back(v);
	G[v].push_back(u);
}
//深度优先遍历
void dfs(int u){
	vis[u]=1;
	for(int i=0;i<G[u].size();i++){
		int v=G[u][i];
		if(vis[v]) continue;
		dfs(v);
	}
}
//广度优先遍历
void bfs(int s){
	vis[s]=1;q.push(s);
	while(!q.empty()){
		int u=q.front(); q.pop();
		for(int i=0;i<G[u].size();i++){
			int v=G[u][i];
			if(vis[v]) continue;
			vis[v]=1; q.push(v);
		}
	}
}

树的直径

const int N=1e6+10;
int n,m,dis[N],cur,mx,tot,head[N];

struct Edge{
	int u,v,w,next;
}G[2*N];

void addedge(int u,int v,int w){
	G[++tot].u=u;G[tot].v=v;G[tot].w=w;G[tot].next=head[u];head[u]=tot;
	G[++tot].u=v;G[tot].v=u;G[tot].w=w;G[tot].next=head[v];head[v]=tot;
}

void dfs(int u,int fa){
	for(int i=head[u];i;i=G[i].next){
		int v=G[i].v;
		if(v==fa) continue;
		dis[v]=dis[u]+G[i].w;
		if(dis[v]>mx){
			mx=dis[v];
			cur=v;
		}
		dfs(v,u);
	}
}


int main(){
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		addedge(u,v,w);
	}
	dfs(1,0);
	mx=0;
	memset(dis,0,sizeof(dis));
	dfs(cur,0);
	printf("%d\n",mx);
	return 0;
}

模板题:TWO

树的重心

const int N=1e6+10;
const int inf=0x7f7f7f;
int f[N],size[N],n;
int rt,sum;
vector<int> G[N];
void addedge(int u,int v){
	G[u].push_back(v);
	G[v].push_back(u);
}

void getrt(int u,int fa){
	size[u]=1;f[u]=0;
	for(int i=0;i<G[u].size();i++){
		int v=G[u][i];
		if(v==fa) continue;
		getrt(v,u);
		size[u]+=size[v];
		f[u]=max(f[u],size[v]);
	}
	f[u]=max(f[u],sum-size[u]);
	if(f[u]<f[rt]) rt=u;
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		addedge(u,v);
	}
	rt=0;sum=n;f[0]=inf;getrt(1,0);
	printf("%d\n",rt);
	return 0;
}

##最小生成树

prim

const int N=3010;
int a[N][N],d[N],ans;
bool vis[N];
int n,m;

void prim(){
	memset(d,0x3f,sizeof(d));
	memset(vis,0,sizeof(vis));
	d[1]=0;
	for(int i=1;i<=n-1;i++){
		int x=0;
		for(int j=1;j<=n;j++){
			if(!vis[j]&&(x==0||d[j]<d[x])) x=j;
		}
		vis[x]=1;
		for(int j=1;j<=n;j++) 
			if(!vis[j])
				d[j]=min(d[j],a[x][j]);
	}
} 

int main(){
	cin >> n >> m;
	memset(a,0x3f,sizeof(a));
	for(int i=1;i<=n;i++) a[i][i]=0;
	for(int i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		a[x][y]=a[y][x]=z;
	}
	prim();
	for(int i=2;i<=n;i++) ans+=d[i];
	cout << ans << endl;
	return 0;
}

kruskal

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

struct node{
	int u,v,w;
}edge[500010];
int fa[100010],n,m,ans;

bool cmp(node a,node b){
	return a.w<b.w;
}

int find(int x){
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}

void merge(int u,int v){
	u=find(u);v=find(v);
	if(u!=v) fa[u]=v;
}

int main(){
	cin >> n >> m;
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
	}	
	sort(edge+1,edge+1+m,cmp);
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++){
		int u=edge[i].u,v=edge[i].v;
		if(find(u)!=find(v)){
			merge(u,v);
			ans+=edge[i].w;
		}
	}
	cout << ans << endl;
	return 0;
}

最短路

floyd(多源最短路)

const int N=310;
int d[N][N],n,m;

int main(){
	cin >> n >> m;
	memset(d,0x3f,sizeof(d));
	for(int i=1;i<=n;i++) d[i][i]=0;
	for(int i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		d[x][y]=d[y][x]=z;
	} 
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			printf("%d ",d[i][j]);
		}
		puts("");
	}
	return 0;
}

Dijkstra(单源最短路)

priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
const int N=100010,M=1000010;
int head[N],ver[M],edge[M],next[M],d[N];
int n,m,tot;
bool vis[N];

void add(int x,int y,int z){
	ver[++tot]=y;edge[tot]=z;next[tot]=head[x];head[x]=tot;
	ver[++tot]=x;edge[tot]=z;next[tot]=head[y];head[y]=tot;
}

void dijkstra(){
	memset(d,0x3f,sizeof(d));
	d[1]=0;
	q.push(make_pair(0,1));
	while(q.size()){
		int now=q.top().second;q.pop();
		if(vis[now]) continue;
		vis[now]=1;
		for(int i=head[now];i;i=next[i]){
			int v=ver[i],w=edge[i];
			if(d[v]>d[now]+w){
				d[v]=d[now]+w;
				q.push(make_pair(d[v],v));
			}
		}
	}
}

int main(){
	cin >> n >> m;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin >> x >> y >> z;
		add(x,y,z);
	}
	dijkstra();
	for(int i=1;i<=n;i++) printf("%d ",d[i]);
	puts("");
	return 0;
}

SPFA(单源最短路)

const int N=100010,M=1000010;
int head[N],ver[M],edge[M],next[M];
int n,m,tot,d[N];
queue<int> q;
bool vis[N];

void add(int x,int y,int z){
	ver[++tot]=y;edge[tot]=z;next[tot]=head[x];head[x]=tot;
	ver[++tot]=x;edge[tot]=z;next[tot]=head[y];head[y]=tot;
}

void spfa(){
	memset(d,0x3f,sizeof(d));
	d[1]=0;vis[1]=1;
	q.push(1);
	while(!q.empty()){
		int now=q.front();q.pop();vis[now]=0;
		for(int i=head[now];i;i=next[i]){
			int v=ver[i],w=edge[i];
			if(d[v]>d[now]+w){
				d[v]=d[now]+w;
				if(!vis[v]){
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
}

int main(){
	cin >> n >> m;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin >> x >> y >> z;
		add(x,y,z);
	}
	spfa();
	for(int i=1;i<=n;i++) printf("%d ",d[i]);
	puts("");
	return 0;
}
posted @ 2019-08-03 19:58  qjy_73  阅读(375)  评论(0)    收藏  举报