图论模板
[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;
}

浙公网安备 33010602011771号