acm模板.docx
《acm模板.docx》由会员分享,可在线阅读,更多相关《acm模板.docx(36页珍藏版)》请在冰豆网上搜索。
acm模板
拓扑排序:
//基础邻接矩阵的数据结构定义:
typedefstructMy_Graph
{
bool**matrix;//图的邻接矩阵
infro*data;//点的信息
intpoints;//点的个数
intsides;//边的个数
};
//对邻接矩阵的点求入度
voidFindInDegree(My_Graph&T,int*indegree)
{
inti,j;
for(i=0;iindegree[i]=0;
for(i=0;i{
for(j=0;j{
if(T.matrix[j][i]==1)
indegree[i]++;
}//forj
}//fori
}//FindInDegree
//邻接矩阵的建立:
voidInitiGraph(My_Graph&T)
{
cout<<"请输入该矩阵的点的个数和边的个数:
"<cin>>T.points>>T.sides;
while(T.points<=0&&T.sides>0)
{
cout<<"数据不符合规范!
请重新输入!
"<cin>>T.points;
cin>>T.sides;
}//T.ponits
inti,j;
//为邻接矩阵分配合适大小的空间
T.matrix=newbool*[T.points+1];
for(i=0;iT.matrix[i]=newbool[T.points+1];
//输入
for(i=0;ifor(j=0;jcin>>T.matrix[i][j];
T.data=newinfro[T.points+1];
cout<<"请输入"<"<for(i=0;icin>>T.data[i];
}//InitiGraph
//输出拓扑排序的结果
voidTopologicalSort(My_Graph&T)
{
inti;
intv;
int*indgree;
indgree=newint[T.points+1];
SqStackS;
InitStack(S);
FindInDegree(T,indgree);
for(i=0;iif(indgree[i]==0)
Push(S,i);
while(!
StackEmpty(S))
{
Pop(S,i);
cout<<""<for(v=0;v{
if(T.matrix[i][v]!
=0)
{
indgree[v]--;
if(indgree[v]==0)
Push(S,v);
}//if
}//forv
}//while
}//TopologicalSort
};
图的操作:
//基础邻接矩阵的数据结构定义:
typedefstructMy_Graph
{
bool**matrix;//图的邻接矩阵
intpoints;//点的个数
intsides;//边的个数
};
boolStackEmpty(SqStackS)
{
if(S.base==S.top)
returnfalse;
else
returntrue;
}//StackEmpty
//****************************************************************************************************
//寻找第一个邻接的位置
intFirstAdjVex(My_Graph&T,inti)
{
intv;
for(v=0;vif(T.matrix[i][v]==1)
returnv;
return-1;
}//FirstAdjVex
//****************************************************************************************************
//寻找下一个邻接的位置
intNextAdjVex(My_Graph&T,inti,intw)
{
intv;
for(v=w+1;vif(T.matrix[i][v]==1)
returnv;
return-1;
}//NextAdjVex
//****************************************************************************************************
//DFS递归遍历的工具
voidDFS_Recurrence(My_Graph&T,inti,bool*visited)
{
intw;
visited[i]=true;
printf("%3c",i+'A');
for(w=FirstAdjVex(T,i);w>=0;w=NextAdjVex(T,i,w))
{
//cout<if(visited[w]==false)
DFS_Recurrence(T,w,visited);
}//forw
}//DFS_Recurrence
//****************************************************************************************************
//DFS_非递归_工具
voidDFS_Nonrecursive(My_Graph&T,SqStack&S,inti,bool*visited)
{
intu;
intv;
if(visited[i]==false)
{
visited[i]=true;
printf("%5c",'A'+i);
Push(S,i);
while(StackEmpty(S))
{
GetTop(S,i);
u=FirstAdjVex(T,i);
while(u>=0)
{
if(visited[u]==false)
{
printf("%3c",'A'+u);
visited[u]=true;
Push(S,u);
u=FirstAdjVex(T,u);
}
else
{
GetTop(S,v);
u=NextAdjVex(T,v,u);
}
}//while
Pop(S,i);
}//while
}//if
}//DFS_Nonrecursive
//DFS_递归_遍历
voidDFS_Recurrence_Traverse(My_Graph&T)
{
inti;
bool*visited;
visited=newbool[T.points+2];
for(i=0;ivisited[i]=false;
for(i=0;i{
if(visited[i]==false)
DFS_Recurrence(T,i,visited);
}//fori
}//DFS_Recurrence_Traverse
//DFS_非递归_遍历
voidDFS_Nonrecursive_Traverse(My_Graph&T)
{
SqStackS;
InitiStack(S);
inti;
bool*visited;
visited=newbool[T.points+2];
for(i=0;ivisited[i]=false;
for(i=0;i{
if(visited[i]==false)
DFS_Nonrecursive(T,S,i,visited);
}//fori
}//DFS_Nonrecursive_Traverse
//BFS_遍历
voidBFS_Traverse(My_Graph&T)
{
inti;
sqQueueQ;
bool*visited;
visited=newbool[T.points+2];
IninQueue(Q);
for(i=0;ivisited[i]=false;
intw,u;
for(i=0;i{
if(visited[i]==false)
{
printf("%3c",'A'+i);
visited[i]=true;
EnQueue(Q,i);
while(QueueEmpty(Q))
{
DeQueue(Q,u);
for(w=FirstAdjVex(T,u);w>=0;w=NextAdjVex(T,u,w))
{
if(visited[w]==false)
{
printf("%3c",'A'+w);
visited[w]=true;
EnQueue(Q,w);
}
}//forw
}//whilenotnull
}//ifvisited
}//fori
}//BFS_Traverse
//关键路径求VE的函数,并且保存VE点,返回一个拓扑序列,保存在T中
intTopologicalOder(My_Graph&G,SqStack&T,int*ve)
{
intcout=0;
inti,j,k,v;
int*indegree;
indegree=newint[G.points+1];
SqStackS;
InitStack(S);
for(i=0;iindegree[i]=ve[i]=0;
FindInDegree(G,indegree);
for(i=0;iif(indegree[i]==0)
Push(S,i);
while(!
StackEmpty(S))//栈不为空,表示栈中还存在的有入度为0的点
{
Pop(S,j);
Push(T,j);//压入一个拓扑序列中
cout++;
for(v=0;v{
if(G.matrix[j][v]!
=0)
{
indegree[v]--;
if(indegree[v]==0)
Push(S,v);
if(ve[j]+G.matrix[j][v]>ve[v])//动态转移,找到(最大)最早发生时间
ve[v]=ve[j]+G.matrix[j][v];
}//ifG.matrix[j][v]!
=0
}//forj
}//while
if(coutreturn0;
else
return1;
}//TopologicalOder
//求关键路径的主函数
voidGriticalPath(My_GraphM)
{
inti,j,k,v;
int*ve,*vl,e,l;
ve=newint[M.points+1];
vl=newint[M.points+1];
SqStackT;
InitStack(T);
if(!
TopologicalOder(M,T,ve))
{
cout<<"图中有环!
"<exit(0);
}
for(i=0;i最大的值,即是出度为0点
vl[i]=ve[M.points-1];
while(!
StackEmpty(T))
{
for(Pop(T,j),v=0;v{
if(M.matrix[j][v]!
=0)
{
if(vl[v]-M.matrix[j][v]vl[j]=vl[v]-M.matrix[j][v];
}//if
}//forv
}//while
for(i=0;i{
for(v=0;v{
if(M.matrix[i][v]!
=0)//寻找最短路径(当活动发生时间和开始时间相当即为最短路径的点)
{
e=ve[i];
l=vl[v]-M.matrix[i][v];
if(e==l)
{
cout<<"点"<cout<}
}
}//forv
}//for
}//GriticalPath
};
//用于将字符加入到字符串中
voidadd(charp[],inti,int&len,intstart)
{
if(len==0)//设置起点为,预订的点(A)
p[len++]='A'+start;
p[len]=char('A'+i);//记录
p[len+1]='\0';//设置结束符
len++;//长度加1
}//add
//将字符串清理
voidempty(charp[])//将字符清理,消除乱码
{
memset(p,0,sizeof(p));
}//empty
//复制路径函数
voidcopy(chara[],charb[])
{
strcpy(a,b);
}//copy
public:
//邻接矩阵的建立:
voidInitiGraph(My_Graph&T)
{
cout<<"请输入该矩阵的点的个数和边的个数:
"<cin>>T.points>>T.sides;
while(T.points<=0&&T.sides>0)
{
cout<<"数据不符合规范!
请重新输入!
"<cin>>T.points;
cin>>T.sides;
}//T.ponits
inti,j;
//为邻接矩阵分配合适大小的空间
T.matrix=newint*[T.points+1];
for(i=0;iT.matrix[i]=newint[T.points+1];
//输入
for(i=0;ifor(j=0;jcin>>T.matrix[i][j];
T.data=newinfor[T.points+1];
cout<<"请输入"<"<for(i=0;icin>>T.data[i];
}//InitiGraph
//老师所讲的方法,利用字符串保存路径
voidShorterstPath1_DIJ(constMy_GraphM,intstart,Elem*D,char*p[])
{
constintMAX=999999;
inti,j,k;
intmin;
bool*S;
S=newbool[M.points+1];
int*len;
len=newint[M.points];
//初始化
for(i=0;i{
len[i]=0;//将每一个点的路径初始为空
S[i]=false;//每一个点为设置没有加入到集合S中
D[i]=M.matrix[start][i];//保存初始的路径长度
if(D[i]{
p[i][0]='A'+start;
len[i]++;
add(p[i],i,len[i],start);
}
else
empty(p[i]);
}//fori
S[start]=1;//将起点加入到集合S中
intpos;//最短路径的位置
for(i=1;i{
min=MAX;
pos=0;
for(j=0;j{
if(S[j]!
=true&&min>D[j])
{
min=D[j];
pos=j;
}
}
S[pos]=true;//加入到S集合中
for(k=0;k{
if(S[k]!
=true&&D[k]>M.matrix[pos][k]+min)
{
D[k]=M.matrix[pos][k]+min;//更新路径长度
copy(p[k],p[pos]);//保存和设置路径
len[k]=strlen(p[pos]);
add(p[k],k,len[k],start);
}//if
}//fork
}//fori
}//ShorterstPath1_DIJ
//******************************************************************************
//普丽斯姆算法-------生成最小生成数的边:
在运行的过程中输出连接的边和相应的权值--
voidMiniSpanTree_PRIM(My_Graph&M)
{
inti,k;
intchioce;//代表每一个选取的节点
int*closed;//用于记录装入了的点,默认从第一个点装入了
closed=newint[M.points+1];
//对辅助数组进行初始化
closed[0]=0;
for(i=1;iclosed[i]=M.matrix[0][i];
//循环判定
for(k=1;k{
chioce=minimum(M.points,closed);
cout<<"第"<"<//更新数组
closed[chioce]