zoukankan      html  css  js  c++  java
  • 德克萨斯长角牛 --最短路径

    题目

    没事回顾一下最短路径算法。练练手。。

    spfa 解法

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    struct node {
         int v,w,next;
    };
    const int MAX=9999999999;
    node edge[32500];
    int head[2510];
    int cnt;//记录下biao
    int ts,te,t,c;
    
    void add(int u,int v,int w)
    {
         edge[cnt].w=w;
         edge[cnt].v=v;
         edge[cnt].next=head[u];
         head[u]=cnt++;
    }
    
    void SPFA()
    {
         int i,u,v;//u从Q中取出的点,v找到的点
         int dis[2510];
         int flag[2510];
         bool vis[2510];
         deque<int> que;
         
         fill(dis,dis+t+1,MAX);
         memset(flag,0,sizeof(flag));
         memset(vis,false,sizeof(vis));
         dis[ts]=0;
         que.push_back(ts);
         while(!que.empty())
         {
              u=que.front();
              que.pop_front();
              vis[u]=false;
              for(i=head[u];i!=-1;i=edge[i].next)
              {
                   v=edge[i].v;
                   if(dis[v]>dis[u]+edge[i].w)
                   {
                        dis[v]=dis[u]+edge[i].w;
                        if(!vis[v])
                        {
                             vis[v]=true;
                             flag[v]++;
                             if(flag[v]>=t)
                                  return ;
                             if(!que.empty()&&dis[v]<dis[que.front()])
                                  que.push_front(v);
                             else
                                  que.push_back(v);
                        }
                   }
              }
         }
         printf("%d
    ",dis[te]);
    }
    int main()
    {
         scanf("%d%d%d%d",&t,&c,&ts,&te);
         memset(head,-1,sizeof(head));
         cnt=0;
         int u,v,w;
         while(c--)
         {
              scanf("%d%d%d",&u,&v,&w);
              add(u,v,w);
              add(v,u,w);
         }
         SPFA();
         return 0;
    }
         

    dijkstra解法,直接套用的模板

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    #define MAX 9999999
    
    using namespace std;
    //pair 的first 保存的为最短距离, second保存的为顶点编号
    typedef pair<int, int >P;//对组  不知道请自行百度   
    
    struct node
    {
        int v, w;//v 为到达的点, w为权重
        int next;//记录下一个结构体的位置 ,就向链表的next功能是一样的
    };
    node edge[22003];//存所有的边,因为是无向图,所以*2
    int cnt;//结构体的下标
    int n, s, t;//n 点数,s 起点,t止点
    int head[3203];//和链表的头指针数组是一样的。只不过此处head[u]记录的为最后加入 edge 的且与u相连的边在 edge 中的位置,即下标
    
    void add(int u, int v, int w)//加边操作
    {
        edge[cnt].v = v;
        edge[cnt].w = w;
        edge[cnt].next = head[u];//获得下一个结构体的位置
        head[u] = cnt++;//记录头指针的下标
    }
    
    void dijkstra()
    {
        int dis[3203];//最短路径数组
        int i, v;//v保存从队列中取出的数的第二个数  也就是顶点的编号
        priority_queue<P,vector<P>,greater<P> >que;//优先队列 从小到大
        node e;//保存边的信息,为了书写方便
        P p;//保存从队列取出的数值
    
        fill(dis,dis+n+1,MAX);//初始化,都为无穷大
        dis[s] = 0;//s—>s  距离为0
        que.push(P(0,s));//放入距离 为0   点为s
        while(!que.empty()){
            p = que.top();//取出队列中最短距离最小的对组
            que.pop();//删除
            v = p.second;//获得最短距离最小的顶点编号
            if(dis[v] < p.first)//若取出的不是最短距离
                continue;//则进行下一次循环
            for(i=head[v];i!=-1;i=edge[i].next)//对与此点相连的所有的点进行遍历
            {
                e = edge[i];//为了书写的方便。
                if(dis[e.v]>dis[v]+e.w){//进行松弛
                    dis[e.v]=dis[v]+e.w;//松弛成功
                    que.push(P(dis[e.v],e.v));//讲找到的松弛成功的距离 和顶点放入队列
                }
            }
        }
        printf("%d
    ",dis[t]==MAX?-1:dis[t]);//输出结果
    }
    
    int main()
    {
        int m, u, v, w;
    
      scanf("%d %d",&n,&m);//获取点数  边数
      scanf("%d %d",&s,&t);
            cnt = 0;//结构体下标从0开始
            memset(head,-1,sizeof(head));//初始化head[N]数组
            while(m--){
                scanf("%d %d %d",&u,&v,&w);//获取u,v,w(u,v)
                add(u,v,w);//加边
                add(v,u,w);//加边
            }
            //scanf("%d %d",&s,&t);//获取起止点
            dijkstra();
        
        return 0;
    }
    View Code
  • 相关阅读:
    python-观察者模式
    python-迭代器模式
    python-策略模式
    python-组合模式
    python-享元模式
    python-代理模式
    虚基类与虚继承
    指针与地址的关系
    大数相加和大数相乘以及打印从1到最大的n位数
    各种排序实现以及稳定性分析
  • 原文地址:https://www.cnblogs.com/WDKER/p/5506083.html
Copyright © 2011-2022 走看看