数据结构上机题目--dijkstra

来源:互联网 发布:网络6524是什么意思啊 编辑:程序博客网 时间:2024/05/12 13:25

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 80 2 1000 5 101 5 55 4 500 3 303 2 603 4 204 2 100 2output:600-->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 80 20 50 31 55 44 23 23 4output:0-->1-->3-->5-->4-->2*/


 

原创粉丝点击