标程_图论
图的遍历
深搜+邻接矩阵
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,sum;
bool a[110][110],b[110];
void DFS(int dep)
{
int i;
b[dep]=0;
sum++;
for(i=1;i<=n;i++)
if(b[i]&&a[dep][i])
DFS(i);
return;
}
int main()
{
int x,y,ans=0,i;
memset(a,false,sizeof(a));
memset(b,true,sizeof(b));
scanf("%d",&n);
for(scanf("%d%d",&x,&y);x||y;a[x][y]=a[y][x]=1,scanf("%d%d",&x,&y));
for(i=1;i<=n;i++)
if(b[i])
{
sum=0;
DFS(i);
ans=max(ans,sum);
}
printf("%d",ans);
return 0;
}
深搜+邻接表
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct jgt
{
int x,y,nxt;
}a[10010];
int n,sum,tot=0,head[110];
bool b[110];
void add(int x,int y)
{
tot++;
a[tot].x=x;
a[tot].y=y;
a[tot].nxt=head[x];
head[x]=tot;
return;
}
void DFS(int dep)
{
int i;
b[dep]=0;
sum++;
for(i=head[dep];i;i=a[i].nxt)
if(b[a[i].y])
DFS(a[i].y);
return;
}
int main()
{
int x,y,ans=0,i;
memset(a,false,sizeof(a));
memset(b,true,sizeof(b));
memset(head,0,sizeof(head));
scanf("%d",&n);
for(scanf("%d%d",&x,&y);x||y;add(x,y),add(y,x),scanf("%d%d",&x,&y));
for(i=1;i<=n;i++)
if(b[i])
{
sum=0;
DFS(i);
ans=max(ans,sum);
}
printf("%d",ans);
return 0;
}
广搜+邻接矩阵
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,sum;
bool a[110][110],b[110];
int c[10010];
void BFS(int dep)
{
int l,r,i;
b[dep]=0;
c[0]=dep;
for(l=r=0;l<=r;l++)
{
for(i=1;i<=n;i++)
{
if(a[c[l]][i]&&b[i])
{
b[i]=0;
c[++r]=i;
}
}
}
sum=r+1;
return;
}
int main()
{
int x,y,ans=0,i;
memset(a,false,sizeof(a));
memset(b,true,sizeof(b));
scanf("%d",&n);
for(scanf("%d%d",&x,&y);x||y;a[x][y]=a[y][x]=1,scanf("%d%d",&x,&y));
for(i=1;i<=n;i++)
if(b[i])
{
sum=0;
BFS(i);
ans=max(ans,sum);
}
printf("%d",ans);
return 0;
}
广搜+邻接表
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct jgt
{
int x,y,nxt;
}a[10010];
int n,sum,tot=0,head[110],c[10010];
bool b[110];
void add(int x,int y)
{
tot++;
a[tot].x=x;
a[tot].y=y;
a[tot].nxt=head[x];
head[x]=tot;
return;
}
void BFS(int dep)
{
int l,r,i;
b[dep]=0;
c[0]=dep;
for(l=r=0;l<=r;l++)
{
for(i=head[c[l]];i;i=a[i].nxt)
{
if(b[a[i].y])
{
b[a[i].y]=0;
c[++r]=a[i].y;
}
}
}
sum=r+1;
return;
}
int main()
{
int x,y,ans=0,i;
memset(a,false,sizeof(a));
memset(b,true,sizeof(b));
memset(head,0,sizeof(head));
scanf("%d",&n);
for(scanf("%d%d",&x,&y);x||y;add(x,y),add(y,x),scanf("%d%d",&x,&y));
for(i=1;i<=n;i++)
if(b[i])
{
sum=0;
BFS(i);
ans=max(ans,sum);
}
printf("%d",ans);
return 0;
}
广搜+STL
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct jgt
{
int x,y,nxt;
}a[10010];
int n,sum,tot=0,head[110];
bool b[110];
queue<int>c;
void add(int x,int y)
{
tot++;
a[tot].x=x;
a[tot].y=y;
a[tot].nxt=head[x];
head[x]=tot;
return;
}
void BFS(int dep)
{
int i;
b[dep]=0;
for(c.push(dep);!c.empty();c.pop())
{
for(i=head[c.front()];i;i=a[i].nxt)
{
if(b[a[i].y])
{
b[a[i].y]=0;
c.push(a[i].y);
sum++;
}
}
}
return;
}
int main()
{
int x,y,ans=0,i;
memset(a,false,sizeof(a));
memset(b,true,sizeof(b));
memset(head,0,sizeof(head));
scanf("%d",&n);
for(scanf("%d%d",&x,&y);x||y;add(x,y),add(y,x),scanf("%d%d",&x,&y));
for(i=1;i<=n;i++)
if(b[i])
{
sum=1;
BFS(i);
ans=max(ans,sum);
}
printf("%d",ans);
return 0;
}
最小生成树
prim+邻接矩阵
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int n,a[110][110],ans=0,tot=0,mn[110];
bool d[110];
void input()
{
int i,j;
memset(mn,100,sizeof(mn));
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&a[i][j]);
return;
}
void prim()
{
int i,j,w;
memset(d,true,sizeof(d));
mn[1]=0;
for(i=1;i<n;i++)
{
for(w=0,j=1;j<=n;j++)
if(d[j]&&mn[j]<mn[w])
w=j;
d[w]=0;
for(j=1;j<=n;j++)
if(d[j]&&a[w][j]<mn[j])
mn[j]=a[w][j];
}
for(i=1;i<=n;i++)
ans+=mn[i];
return;
}
int main()
{
input();
prim();
printf("%d",ans);
return 0;
}
prim+邻接表
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int n,a[110][110],ans=0,tot=0,mn[110],head[110];
bool d[110];
struct jgt
{
int x,y,w,nst;
}f[10010];
void input()
{
int i,j;
memset(mn,100,sizeof(mn));
memset(head,0,sizeof(head));
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j])
{
tot++;
f[tot].x=i;
f[tot].y=j;
f[tot].w=a[i][j];
f[tot].nst=head[i];
head[i]=tot;
}
}
return;
}
void prim()
{
int i,j,w;
memset(d,true,sizeof(d));
mn[1]=0;
for(i=1;i<n;i++)
{
for(w=0,j=1;j<=n;j++)
if(d[j]&&mn[j]<mn[w])
w=j;
d[w]=0;
for(j=head[w];j;j=f[j].nst)
if(d[f[j].y]&&a[w][f[j].y]<mn[f[j].y])
mn[f[j].y]=a[w][f[j].y];
}
for(i=1;i<=n;i++)
ans+=mn[i];
return;
}
int main()
{
input();
prim();
printf("%d",ans);
return 0;
}
kruskal
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int n,a[110][110],ans=0,tot=0,b[110];
bool d[110];
struct jgt
{
int x,y,w;
}f[10010];
int bcj(int x)
{
if(b[x]==x)
return x;
b[x]=bcj(b[x]);
return b[x];
}
bool cmp(jgt t1,jgt t2)
{
return t1.w<t2.w;
}
void input()
{
int i,j;
scanf("%d",&n);
for(i=1;i<=n;b[i]=i,i++)
for(j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
if(i<j)
{
f[tot].x=i;
f[tot].y=j;
f[tot++].w=a[i][j];
}
}
return;
}
void kruskal()
{
int i,x;
sort(f,f+tot,cmp);
for(i=0;n;i++)
{
if(bcj(f[i].x)!=bcj(f[i].y))
{
n--;
ans+=f[i].w;
b[bcj(f[i].x)]=bcj(f[i].y);
}
}
return;
}
int main()
{
input();
kruskal();
printf("%d",ans);
return 0;
}
最短路
floyd
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,dx,dy;
double a[110][110],x[110],y[110];
void input()
{
int i,j;
memset(a,0x7f7f7f,sizeof(a));
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&x[i],&y[i]);
a[i][i]=0;
}
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d%d",&dx,&dy);
a[dx][dy]=a[dy][dx]=sqrt((x[dx]-x[dy])*(x[dx]-x[dy])+(y[dx]-y[dy])*(y[dx]-y[dy]));
}
scanf("%d%d",&dx,&dy);
return;
}
void floyed()
{
int i,j,k,w;
for(k=1;k<=n;k++)
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
if(a[i][j]>a[i][k]+a[k][j])
a[i][j]=a[j][i]=a[i][k]+a[k][j];
return;
}
int main()
{
input();
floyed();
printf("%.2lf",a[dx][dy]);
return 0;
}
dijkstra(n^2)
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int e[3010][3010],dis[3010],head[3010],tot;
bool d[3010];
void DIJ(int n)
{
int i,j,mn,w;
for(i=1;i<=n;i++)
{
e[i][i]=0;
dis[i]=e[1][i];
}
dis[1]=0;
d[1]=1;
for(i=1;i<n;i++)
{
mn=10000000;
for(j=2;j<=n;j++)
{
if(!d[j]&&dis[j]<mn)
{
w=j;
mn=dis[j];
}
}
d[w]=1;
for(j=2;j<=n;j++)
{
if(!d[j]&&dis[w]+e[w][j]<dis[j])
dis[j]=dis[w]+e[w][j];
}
}
return;
}
int main()
{
int n,m,i,u,v,w;
memset(e,1,sizeof(e));
scanf("%d%d",&n,&m);
tot=0;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
e[u][v]=e[v][u]=w;
}
DIJ(n);
for(i=1;i<=n;i++)
printf("%d %d\n",i,dis[i]);
return 0;
}
dijkstra堆优化
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct jgt
{
int w,s;
};
struct NOTE
{
int x,y,nxt,s;
}f[3010];
bool operator < (const jgt &a,const jgt &b)
{
return a.s>b.s;
}
priority_queue<jgt>q;
int e[3010][3010],dis[3010],head[3010],tot;
bool d[3010];
void DIJ(int n)
{
jgt tem,temp;
int i,j,mn,w,v;
for(i=1;i<=n;i++)
{
e[i][i]=0;
dis[i]=e[1][i];
}
for(i=head[1];i>0;i=f[i].nxt)
{
tem.w=f[i].y;
tem.s=dis[f[i].y];
q.push(tem);
}
for(dis[1]=0,d[1]=1;!q.empty();)
{
tem=q.top();
q.pop();
d[tem.w]=1;
for(j=head[tem.w];j>0;j=f[j].nxt)
{
if(!d[f[j].y]&&tem.s+e[tem.w][f[j].y]<dis[f[j].y])
{
dis[f[j].y]=tem.s+e[tem.w][f[j].y];
temp.w=f[j].y;
temp.s=dis[f[j].y];
q.push(temp);
}
}
}
return;
}
void add(int u,int v,int w)
{
f[++tot].x=u;
f[tot].y=v;
f[tot].s=w;
f[tot].nxt=head[u];
head[u]=tot;
return;
}
int main()
{
int n,m,i,u,v,w;
memset(e,1,sizeof(e));
scanf("%d%d",&n,&m);
tot=0;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
e[u][v]=e[v][u]=w;
}
DIJ(n);
for(i=1;i<=n;i++)
printf("%d %d\n",i,dis[i]);
return 0;
}
ford
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,dx,dy;
double x[110],y[110],dis[110];
struct jgt
{
int x,y;
double s;
}b[10000];
void input()
{
int i,j;
scanf("%d",&n);
dis[0]=100000000;
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&x[i],&y[i]);
dis[i]=100000000;
}
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&b[i].x,&b[i].y);
b[i].s=sqrt((x[b[i].x]-x[b[i].y])*(x[b[i].x]-x[b[i].y])+(y[b[i].x]-y[b[i].y])*(y[b[i].x]-y[b[i].y]));
}
scanf("%d%d",&dx,&dy);
return;
}
void ford()
{
int i,j,k,w;
bool y=1;
dis[dx]=0;
for(i=1;y&&i<n;i++)
{
y=0;
for(j=1;j<=m;j++)
{
if(dis[b[j].x]+b[j].s<dis[b[j].y])dis[b[j].y]=dis[b[j].x]+b[j].s,y=1;
if(dis[b[j].y]+b[j].s<dis[b[j].x])dis[b[j].x]=dis[b[j].y]+b[j].s,y=1;
}
}
return;
}
int main()
{
input();
ford();
printf("%.2lf",dis[dy]);
return 0;
}
spfa_bfs
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
bool d[300010];
int n,m,dis[300010],head[300010],tot=0,a[300010];
struct jgt
{
int x,y,nxt,s;
}f[5000001];
queue<int> q;
void add(int x,int y)
{
f[++tot].x=x;
f[tot].y=y;
f[tot].s=0;
f[tot].nxt=head[x];
head[x]=tot;
return;
}
void input()
{
int i,x,y,z;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y);
add(x+n,y+n);
add(x+n+n,y+n+n);
if(z==2)
{
add(y,x);
add(y+n,x+n);
add(y+n+n,x+n+n);
}
}
for(i=1;i<=n;i++)
{
f[++tot].x=i;
f[tot].y=i+n;
f[tot].s=-a[i];
f[tot].nxt=head[i];
head[i]=tot;
f[++tot].x=i+n;
f[tot].y=i+n+n;
f[tot].s=a[i];
f[tot].nxt=head[i+n];
head[i+n]=tot;
}
return;
}
void SPFA()
{
int l,r,i;
memset(d,0,sizeof(d));
memset(dis,-0x7f7f,sizeof(dis));
dis[1]=0;
for(q.push(1),d[1]=1;!q.empty();q.pop())
{
for(i=head[q.front()];i;i=f[i].nxt)
if(dis[f[i].y]<dis[q.front()]+f[i].s)
{
dis[f[i].y]=dis[q.front()]+f[i].s;
if(!d[f[i].y])
{
q.push(f[i].y);
d[f[i].y]=1;
}
}
d[q.front()]=0;
}
return;
}
int main()
{
input();
SPFA();
printf("%d",dis[3*n]);
return 0;
}
spfa_dfs
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct jgt
{
int w,s;
};
struct NOTE
{
int x,y,nxt,s;
}f[3010];
int e[3010][3010],dis[3010],head[3010],tot;
bool d[3010];
void add(int u,int v,int w)
{
f[++tot].x=u;
f[tot].y=v;
f[tot].s=w;
f[tot].nxt=head[u];
head[u]=tot;
return;
}
bool SPFA(int s)
{
int i;
if(d[s])
return 1;
d[s]=1;
for(i=head[s];i>0;i=f[i].nxt)
if (dis[s]+e[s][f[i].y]<dis[f[i].y])
{
dis[f[i].y]=dis[s]+e[s][f[i].y];
if (SPFA(f[i].y))
return 1;
}
d[s]=0;
return 0;
}
int main()
{
int n,m,i,u,v,w;
memset(e,1,sizeof(e));
memset(d,0,sizeof(d));
memset(dis,1,sizeof(dis));
scanf("%d%d",&n,&m);
tot=0;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
e[u][v]=e[v][u]=w;
}
dis[1]=0;
if (SPFA(1))
printf("-1");
else
for(i=1;i<=n;i++)
printf("%d %d\n",i,dis[i]);
return 0;
}
最小环
for(k=1;k<=n;k++)
{
for(i=1;i<=k-1;i++)
for(j=i+1;j<=k-1;j++)
answer=min(answer,dis[i][j]+g[j][k]+g[k][i]);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
有向图的强连通分量Kosaraju
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,c[1010],lenc=0;
bool a[210][210],b[210],f[210][210];
void DFS(int dep)
{
int i;
b[dep]=0;
for(i=1;i<=n;i++)
if(b[i]&&a[dep][i])
{
DFS(i);
c[++lenc]=i;
}
return;
}
void dfs(int dep)
{
int i;
b[dep]=0;
for(i=1;i<=n;i++)
if(b[i]&&f[dep][i])
dfs(i);
return;
}
int main()
{
int x,j,ans=0,i;
memset(a,false,sizeof(a));
memset(b,true,sizeof(b));
scanf("%d",&n);
for(i=1;i<=n;i++)
for(scanf("%d",&x);x;a[i][x]=1,scanf("%d",&x));
for(i=1;i<=n;i++)
if(b[i])
DFS(i),c[++lenc]=i,ans++;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(a[i][j])
f[j][i]=1;
memset(b,true,sizeof(b));
for(i=n;i>=1;i--)
if(b[c[i]])
dfs(i),ans++;
printf("%d",ans);
return 0;
}
拓扑排序
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int ans[100010],sum=0,tot=0,n,m,head[100010],ins[100010];
queue<int> q;
struct jgt
{
int x,y,nxt;
}f[200010];
void input()
{
int i;
memset(ins,0,sizeof(ins));
memset(ans,0,sizeof(ans));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
tot++;
scanf("%d%d",&f[tot].y,&f[tot].x);
f[tot].nxt=head[f[tot].x];
head[f[tot].x]=tot;
ins[f[tot].y]++;
}
return;
}
void topsort()
{
int i;
for(i=1;i<=n;i++)
if(!ins[i])
q.push(i);
for(;!q.empty();q.pop(),sum++)
{
for(i=head[q.front()];i;i=f[i].nxt)
{
ins[f[i].y]--;
if(!ins[f[i].y])
{
ans[f[i].y]=ans[q.front()]+1;
q.push(f[i].y);
}
}
}
return;
}
void output()
{
int i,answer=n*100;
if(sum<n)
{
printf("-1");
return;
}
for(i=1;i<=n;i++)
answer+=ans[i];
printf("%d",answer);
return;
}
int main()
{
input();
topsort();
output();
return 0;
}