dijkstra:
/*************************************************************************
* author:crazy_石头
* algorithm:Dijkstra
* date:2013/09/29
* 程序功能:最短路
* 算法流程:初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为
* 从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。
* Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,
* 同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的
* 最短路径长度。
**************************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
#define INF 1<<29
#define A system("pause")
const int maxn=1000;
int map[101][101],d[101],mark[101];//d为距离向量;
int pre[maxn];//记录每个节点的前驱最终形成一条路径;
int m,n,s,e;
inline int min(int a,int b)
{
return a<b?a:b;
}
inline void Dijkstra()
{
int i,j,k,min;
memset(mark,0,sizeof(mark));
for(i=0;i<n;i++)
{
d[i]=map[s][i];
if(d[i]==INF)
pre[i]==0;
else
pre[i]=s;
}
d[s]=0;
// 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中
// 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度;
for(i=0;i<n;i++)
{
min=INF;
for(j=0;j<n;j++)
{
if(!mark[j]&&d[j]<min)
{
k=j;
min=d[j];//找出未访问的点的最小的d[j]值;
}
}
if(min==INF)
break;
mark[k]=1;//k已经放入了集合S;
//更新距离,记录前驱;
for(j=0;j<n;j++)
{
if(!mark[j]&&d[j]>d[k]+map[k][j])
{
d[j]=d[k]+map[k][j];
pre[j]=k;
}
}
}
if(d[e]!=INF)
cout<<d[e]<<endl;
else
cout<<-1<<endl;
}
inline void printpath(int pre[],int s,int e)//打印从s到e的路径;
{
int path[maxn];
int cnt=0;
path[cnt]=e;
cnt++;
int cur=pre[e];
while(cur!=s)
{
path[cnt]=cur;
cnt++;
cur=pre[cur];
}
path[cnt]=s;
printf("%d-->",s);
for(int i=cnt-1;i>=0;i--)
i==0?printf("%d\n",path[i]):printf("%d-->",path[i]);
}
int main()
{
int a,b,w,i,j;
while(cin>>n>>m)
{
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
map[i][j]=INF;
}
}
for(i=0;i<m;i++)
{
cin>>a>>b>>w;
map[a][b]=min(w,map[a][b]);
}
printf("输入起始点:\n");
cin>>s>>e;
printf("这是从%d到%d的最短距离\n",s,e);
Dijkstra();
printf("这是其经过的路径:");
printpath(pre,s,e);
}
return 0;
}
/*
test cases:
6 8
0 2 100
0 5 10
1 5 5
5 4 50
0 3 30
3 2 60
3 4 20
4 2 10
0 2
output:60
0-->3-->4-->2
*/
toposort:
/*************************************************************************
* author:crazy_石头
* algorithm:toposort
* date:2013/10/20
* 程序功能:MST
* 算法流程:每一步总是输出当前无前趋(即人度为零)的顶点,其抽象算法可描述为:
NonPreFirstTopSort(G)
{//优先输出无前趋的顶点
while(G中有人度为0的顶点)do
{
从G中选择一个人度为0的顶点v且输出之;
从G中删去v及其所有出边;
}
if(输出的顶点数目<|V(G)|)
//若此条件不成立,则表示所有顶点均已输出,排序成功。
Error("G中存在有向环,排序失败!");
}
**************************************************************************/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
int map[505][505];
int indegree[505];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)
break;
int i,a,b;
memset(map,0,sizeof(map));
for(i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
map[a][b]=1;
}
memset(indegree,0,sizeof(indegree));
int j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
if(map[i][j])
indegree[j]++;
}
priority_queue<int,vector<int>,greater<int> > q;
for(i=0;i<n;i++)
if(indegree[i]==0)
q.push(i);
int count=0;
while(!q.empty())
{
int t=q.top();
q.pop();
printf("当前访问点为:%d\n",t);
count++;
for(i=0;i<n;i++)
{
if(map[t][i])
{
indegree[i]--;
if(indegree[i]==0)
q.push(i);
}
}
}
if(count==n)
printf("拓扑结果为:YES\n");
else
printf("拓扑结果为:NO\n");
}
return 0;
}
/*test:
6 8
0 2
0 5
0 3
1 5
5 4
4 2
3 2
3 4
output:0-->1-->3-->5-->4-->2
*/