版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zimengxueying/article/details/79059322
所有的代码都没有运行过,大意表示出来即可。(可能以后会补充出来)
1 两个搜索和遍历 DFS和BFS
int pre[800];
queue<graph> Q;
stack<graph> S;
void BFS(graph G,int v)//从v开始入队
{
int i;
Q.push(v);
pre[v]=cnt++;//prev[]数组记录的是访问次序
while(!Q.empty()){
i=Q.front();
Q.pop();
for(j=0;j<G->n;j++)
if(G->a[i][j]&&(per[j]==0))
{
Q.push(j);
pre[j]=cnt++;
}
}
}
//广度优先遍历
//每一次遍历都能访问图的一个连通分支,要想访问所有的连通分支那就把所有的顶点
//都访问一遍
void BFS_traverse(graph G)
{
for(i=0;i<G->n;i++)
pre[i]=0;//初始化
for(i=0;i<G->n;i++){
if(pre[i]==0) //若pre[i]!=0意味着还未被访问过,pre[i]可以用来记录访问的次序
BFS(i);
}
}
queue<graph> Q;
stack<graph> S;
void BFS(graph G,int v)//从v开始入队
{
int i;
Q.push(v);
pre[v]=cnt++;//prev[]数组记录的是访问次序
while(!Q.empty()){
i=Q.front();
Q.pop();
for(j=0;j<G->n;j++)
if(G->a[i][j]&&(per[j]==0))
{
Q.push(j);
pre[j]=cnt++;
}
}
}
//广度优先遍历
//每一次遍历都能访问图的一个连通分支,要想访问所有的连通分支那就把所有的顶点
//都访问一遍
void BFS_traverse(graph G)
{
for(i=0;i<G->n;i++)
pre[i]=0;//初始化
for(i=0;i<G->n;i++){
if(pre[i]==0) //若pre[i]!=0意味着还未被访问过,pre[i]可以用来记录访问的次序
BFS(i);
}
}
//类似的可以写出DFS以及DFS_traverse
//并且有递归和非递归的两种形式,也就是显示和引式的使用栈
void DFS(graph G,int v)
{
int i;
pre[v]=cnt++;
for(j=0;j<G->n;j++){ //邻接表只要将这里改为p,p=p->next
if(G->a[i][j]&&pre[j]==0){
DFS(G,j);
}
}
}
void DFS_traverse(graph G)
{
int i;
int cnt=1;
for(i=0;i<G->n;i++){
pre[i]=0;
}
for(i=0;i<G->n;i++){
if(pre[i]==0)
DFS(G,i);
}
}
//并且有递归和非递归的两种形式,也就是显示和引式的使用栈
void DFS(graph G,int v)
{
int i;
pre[v]=cnt++;
for(j=0;j<G->n;j++){ //邻接表只要将这里改为p,p=p->next
if(G->a[i][j]&&pre[j]==0){
DFS(G,j);
}
}
}
void DFS_traverse(graph G)
{
int i;
int cnt=1;
for(i=0;i<G->n;i++){
pre[i]=0;
}
for(i=0;i<G->n;i++){
if(pre[i]==0)
DFS(G,i);
}
}
最短路径问题
2 单源最短路径问题
1 不带负权 Dijktral
利用贪心算法,newdist=c[u][j]+dist[u];其实重点就是比较这两个东西
2 带负权 bellman ford算法
核心代码
for(i=1;i<=nodenum-1;i++){ //除源点外至多经历nodenum-1次
for(j=1;j<=edgenum;j++)//每一次每条边都检测过去
if(dist[Edge[j].v]>dist[Edge[j].u]+Edge[j].weight){
dist[Edge[j].v] = dist[Edge[j].u]+Edge[j].weight;
prev[Edge[j].v] = Edge[j].u;
}
}
for(j=1;j<=edgenum;j++)//每一次每条边都检测过去
if(dist[Edge[j].v]>dist[Edge[j].u]+Edge[j].weight){
dist[Edge[j].v] = dist[Edge[j].u]+Edge[j].weight;
prev[Edge[j].v] = Edge[j].u;
}
}
3 多源最短路径
或者也是利用n次的Dijktra算法
floyd算法
void floyd(){
rep(k,1,n+1)rep(i,1,n+1)rep(j,1,n+1){
e[i][j] = min(e[i][j],e[i][k]+e[k][j]);
}
}
rep(k,1,n+1)rep(i,1,n+1)rep(j,1,n+1){
e[i][j] = min(e[i][j],e[i][k]+e[k][j]);
}
}
核心也就是三重循环
最小生成树问题
MST
1 prim算法以及克鲁斯卡尔算法
//图匹配问题以及求最大匹配问题
//利用匈牙利算法,通过增广矩阵实现最大匹配问题
//利用匈牙利算法,通过增广矩阵实现最大匹配问题
//拓扑排序
//如果拓扑排序的结果唯一,那么该拓扑排序的结果同时也代表了一条哈密顿路径。
//理解有关全序的概念
void tuopu_sort(graph G)
{
//计算每个顶点的入度
//可以用栈来存储
stack<int> s;
int i;
Node *temp;
for(i=0;i<G->n;i++){
temp=arc[i].first;
while(temp){
indegree[temp->index]++;
temp=temp->next;
}
}
//把入度为0的点入栈
for(i=0;i<G->n;i++){
if(!indegree[i]){
s.push(i);
}
}
//用count来计数能不能拓扑排序
int count=0;
while(!s.empty()){
i=s.top();//将栈顶顶点记录下来
s.pop();
//与I 有关的顶点的入度数全部相应的改变
cout<<"出度为"<<i<<" ";
temp=arc[i].fisrtneighbour;
while(temp){
if(!(--indegree[temp->index])){
s.push(temp->index);
temp=temp->next;
}
}
count++;
}
if(count==G->n) {
cout<<endl;
cout<<"可以进行拓扑排序"<<endl;
}
else cout<<"仍有剩余顶点"<<endl;
}
//2 利用DFS隐式的利用递归
void DFS(int n,bool visit[],stack<int> result)
{
visit[n]=1;
Node *temp=G->firstneightbour;
while(temp){
if(!visit[temp->index]){
DFS(G->n,visit,result);
}
temp=temp->next;
}
}
void tuopu_sort2(Graph G)
{
stack<int> result;
bool *visit = new bool [G->n];
memset(visit,0,n);
//DFS算法如下
for(int i=0;i<G->n;i++){
if(!visit[i]){
DFS(i,visit,result);
}
}
//每次都是找入度为0的点,输出时也要逆序输出
for(i=0;i<G->n;i++){
cout<<result.top<<" ";
result.pop();
}
}
void DFS(int n,bool visit[],stack<int> result)
{
visit[n]=1;
Node *temp=G->firstneightbour;
while(temp){
if(!visit[temp->index]){
DFS(G->n,visit,result);
}
temp=temp->next;
}
}
void tuopu_sort2(Graph G)
{
stack<int> result;
bool *visit = new bool [G->n];
memset(visit,0,n);
//DFS算法如下
for(int i=0;i<G->n;i++){
if(!visit[i]){
DFS(i,visit,result);
}
}
//每次都是找入度为0的点,输出时也要逆序输出
for(i=0;i<G->n;i++){
cout<<result.top<<" ";
result.pop();
}
}
先罗列相关知识点,代码后续补充。