2016.08.22
[1]图上的DFS和BFS
1.DFS
#include<iostream>
using namespace std;
const int inf=0x7fffffff;
int n,m,a[25][25],book[25],sum;
void dfs(int step)
{
sum++;//统计到目前为止走了多少步
cout<<step<<" ";//输出当前路径
if(sum==n)//如果全部都走了的话返回上一步
return;
for(int i=1;i<=n;i++)//查找邻接矩阵中位于第step行且可扩展的结点
{
if(a[step][i]==1&&book[i]==0)//判断是否未走过且可扩展
{
book[i]=1;
dfs(i);//扩展这个结点
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)//初始化邻接矩阵
for(int j=1;j<=n;j++)
{
if(i==j)
a[i][j]=0;
else
a[i][j]=inf;
}
int num_1,num_2;
for(int i=1;i<=m;i++)//输入边
{
cin>>num_1>>num_2;
a[num_1][num_2]=1;
a[num_2][num_1]=1;
}
book[1]=1;
dfs(1);
return 0;
}
2.BFS
#include<iostream>
using namespace std;
int a[25][25],book[25],sum,m,n,data[25];
const int inf=0x7fffffff;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)//初始化邻接矩阵
for(int j=1;j<=n;j++)
{
if(i==j)
a[i][j]=0;
else
a[i][j]=inf;
}
int num_1,num_2;
for(int i=1;i<=m;i++)//输入边
{
cin>>num_1>>num_2;
a[num_1][num_2]=1;
a[num_2][num_1]=1;
}
int head=1,tail=1;
data[tail]=1;
book[tail]=1;
tail++;//初始化队列
while(head<tail&&tail<=n)//BFS!
{
int step=data[head];
for(int i=1;i<=n;i++)//扩展头结点之后的尾结点
{
if(book[i]==0&&a[step][i]==1)//可以走
{
book[i]=1;
data[tail]=i;//入队
tail++;
}
if(tail>n)//如果全部都走完了,则直接退出
break;
}
head++;
}
for(int i=1;i<=tail-1;i++)//输出
cout<<data[i]<<" ";
return 0;
}
[2]最短路径和最少转机
1.最短路径
在起点和终点之间存在这许多的路,这些路都有距离。求一条从起点到终点一条最短的路的距离。
#include<iostream>
using namespace std;
const int inf=0x7fffffff;
int book[25],a[25][25],mina=inf,n,m;
void dfs(int step,int l)
{
if(l>mina)//如果当前长度已经超过了最短边而且还没到终点,这条边就没有必要再走下去了
return;
if(step==n)//走到终点要回溯
{
if(l<mina)//更新最小值
mina=l;
return;
}
for(int i=1;i<=n;i++)//尝试这个结点下所有的根节点
{
if(a[step][i]!=inf&&book[i]==0)
{
book[i]=1;
dfs(i,l+a[step][i]);
book[i]=0;
}
}
return;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)//初始化邻接矩阵
for(int j=1;j<=n;j++)
{
if(i==j)
a[i][j]=0;
else
a[i][j]=inf;
}
int q,b,c;
for(int i=1;i<=m;i++)//输入边
{
cin>>q>>b>>c;
a[q][b]=c;
}
book[1]=1;
dfs(1,0);
cout<<mina;//输出最短路径
return 0;
}
[3]基于DP的优化–Floyd算法
这条代码被称为:只有五行的算法。
#include<iostream>
using namespace std;
int a[25][25],m,n;
const int inf=0x7fffffff;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j)
a[i][j]=0;
else
a[i][j]=inf;
}
int num_1,num_2,num_3;
for(int i=1;i<=m;i++)
{
cin>>num_1>>num_2>>num_3;
a[num_1][num_2]=num_3;
}
for(int k=1;k<=n;k++)//把每条可以转的结点都枚举一遍
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{//动态规划!
if(a[i][k]<inf&&a[k][j]<inf) //防止溢出
a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
[4]跑得更快的dijkstra算法
#include<iostream>
using namespace std;
int book[25],a[25][25],m,n,f[25];
const int inf=0x7fffffff;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j)
a[i][j]=0;
else
a[i][j]=inf;
}
int num_1,num_2,num_3;
for(int i=1;i<=m;i++)
{
cin>>num_1>>num_2>>num_3;
a[num_1][num_2]=num_3;
}
book[1]=1;
for(int i=1;i<=n;i++)
f[i]=a[1][i];//根据邻接矩阵来对f[i]进行松弛优化
//f[i]含义:从源结点走到目标结点的最短路径
for(int i=1;i<=n-1;i++)//一共有n-1个结点可以松弛
{
int u,mi=inf;
for(int j=1;j<=n;j++)
{
if(book[j]==0&&f[j]<mi)//找到离源结点最短的一个结点进行松弛
{
mi=f[j];
u=j;
}
}
book[u]=1;
for(int j=1;j<=n;j++)//松弛
{
if(a[u][j]<inf)
{
f[j]=min(f[j],f[u]+a[u][j]);
}
}
}
for(int i=1;i<=n;i++)
cout<<f[i]<<" ";
return 0;
}