ACM比赛模板Word文件下载.docx

上传人:b****3 文档编号:14078978 上传时间:2022-10-18 格式:DOCX 页数:91 大小:41.90KB
下载 相关 举报
ACM比赛模板Word文件下载.docx_第1页
第1页 / 共91页
ACM比赛模板Word文件下载.docx_第2页
第2页 / 共91页
ACM比赛模板Word文件下载.docx_第3页
第3页 / 共91页
ACM比赛模板Word文件下载.docx_第4页
第4页 / 共91页
ACM比赛模板Word文件下载.docx_第5页
第5页 / 共91页
点击查看更多>>
下载资源
资源描述

ACM比赛模板Word文件下载.docx

《ACM比赛模板Word文件下载.docx》由会员分享,可在线阅读,更多相关《ACM比赛模板Word文件下载.docx(91页珍藏版)》请在冰豆网上搜索。

ACM比赛模板Word文件下载.docx

//inf表无穷大

for(j=0;

j<

j++)//找出当前未在最小生成树中边权最小的顶点

if(!

mark[j]&

&

dis[j]<

min)

min=dis[j],flag=j;

mark[flag]=1;

//把该顶点加入最小生成树中

sum+=dis[flag];

//sum加上其边权值

j++) 

//以falg为起点更新到各点是最小权值

if(dis[j]>

mat[flag][j])

dis[j]=mat[flag][j];

returnsum;

//返回边权总和

}

prim算法(边表形式):

structEdge//frm为起点,to为终点,w为边权,nxt指向下一个顶点

//intfrm;

intto,w,nxt;

}edge[M];

intvis[M],head[M],dis[M];

voidaddedge(intcu,intcv,intcw)//生成边的函数

//edge[e].frm=cu;

edge[e].to=cv;

edge[e].w=cw;

edge[e].nxt=head[cu];

head[cu]=e++;

//edge[e].frm=cv;

edge[e].to=cu;

edge[e].nxt=head[cv];

head[cv]=e++;

intprim(intn,intsta)//n为顶点数量,sta为起点

intsum=0;

memset(dis,0x3f,sizeof(dis));

memset(vis,0,sizeof(vis));

for(i=head[sta];

i!

=-1;

i=edge[i].nxt)//遍历与sta点相连的所有顶点

intv=edge[i].to;

dis[v]=edge[i].w;

vis[sta]=1;

//加入到最小生成树中

intm=n-1;

//只生成n-1条边,所以循环n-1次

while(m--)

i++)//找出当前边权最小的边

vis[i]&

dis[i]<

flag=i,min=dis[i];

vis[flag]=1;

//加入到最小生成树中

for(i=head[flag];

i=edge[i].nxt)//更新与flag顶点相连的点的dis

if(edge[i].w<

dis[v])

intmain()

e=0;

//记得初始化

memset(head,-1,sizeof(head));

scanf("

%d%d%d"

&

a,&

b,&

w);

addedge(a,b,w);

.....

prim(n,sta);

return0;

Kruskal算法:

structEdge

intv1,v2,w;

}edge[M],tree[M];

//w为v1顶点到v2顶点的边权

/*

intFind(intparent[],intu)//第1种写法

inttmp=u;

while(paren[tmp]!

=-1)

tmp=parent[tmp];

returntmp;

*/

intFind(intu) 

//第2种写法

if(u!

=parent[u])

parent[u]=Find(paren[u]);

returnparent[u];

boolcmp(Edgea,Edgeb)

returna.w<

b.w;

intKruskal()//parent[]表示集合

intparent[M];

inti,j,sum,vf1,vf2;

sort(edge,edge+E,cmp);

// 

memset(parent,-1,sizeof(parent));

//对应第1种并查集的初始化

//对应第2种并查集的初始化

parent[i]=i;

sum=i=j=0;

while(i<

E&

j<

N-1)//生成的边数为N-1

vf1=Find(parent,edge[i].v1);

//找这两个点的祖先

vf2=Find(parent,edge[i].v2);

if(vf1!

=vf2)//若两个点的祖先不同,说明不在同一集合

parent[vf2]=vf1;

//把vf2点加到vf1点的集合中

tree[j++]=edge[i];

//把边加到tree[]数组中,这句题目没要求可忽略之

sum+=edge[i].w;

//sum加上其边权

i++;

最小生成树--Kruskal算法:

运用数组存点与边的权值

#include<

stdio.h>

stdlib.h>

algorithm>

#defineN150

usingnamespacestd;

intm,n,u[N],v[N],w[N],p[N],r[N];

intcmp(constinti,constintj){returnw[i]<

w[j];

intfind(intx){returnp[x]==x?

x:

p[x]=find(p[x]);

intkruskal()

intcou=0,x,y,i,ans=0;

for(i=0;

i<

n;

i++)p[i]=i;

m;

i++)r[i]=i;

sort(r,r+m,cmp);

i++)

inte=r[i];

x=find(u[e]);

y=find(v[e]);

if(x!

=y){ans+=w[e];

p[x]=y;

cou++;

if(cou<

n-1)ans=0;

returnans;

intmain()

inti,ans;

while(scanf("

%d%d"

m,&

n)!

=EOF&

m)

scanf("

%d%d%d"

u[i],&

v[i],&

w[i]);

ans=kruskal();

if(ans)printf("

%d\n"

ans);

elseprintf("

?

\n"

2.最短路算法

①DIJK

C++代码 

1.#define 

inf 

0x3fffffff 

2.#define 

105 

3. 

4.int 

dist[M], 

map[M][M], 

5.bool 

mark[M];

6. 

7.void 

init 

() 

8.{ 

9. 

int 

i, 

j;

10. 

for 

(i 

1;

<

i++) 

//i==j的时候也可以初始化为0,只是有时候不合适 

11. 

(j 

j++) 

12. 

map[i][j] 

inf;

13.} 

14. 

15.void 

dijk 

(int 

u) 

16.{ 

17. 

j, 

mins, 

v;

18. 

19. 

20. 

dist[i] 

map[u][i];

21. 

mark[i] 

false;

22. 

23. 

mark[u] 

true;

24. 

dist[u] 

0;

//既然上面的map当i==j时不是0,就要这句 

25. 

while 

(1) 

26. 

27. 

mins 

28. 

29. 

if 

(!

mark[j] 

dist[j] 

mins) 

30. 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1