zoukankan      html  css  js  c++  java
  • 热浪

    【题目描述】

    给定一张地图,包含T个城镇(1 <= T <= 2500)和M(1 <= M <= 6200)条直接连接两个城镇的道路,每条道路由起点S、终点E(1 <= S <= T,1 <= E <= T)以及花费C(1 <= C <= 1000)构成,求从起始城镇Start(1 <= Start <= T)到终点城镇End(1 <= End <= T)所能得到的最小总费用是多少。

    【输入描述】

    第一行输入四个整数T、M、Start、End;

    接下来M行,每行输入三个整数S、E、C。

    【输出描述】

    输出一个整数,表示答案。

    【输入样例】

    7 11 5 4

    2 4 2

    1 4 3

    7 2 2

    3 4 3

    5 7 5

    7 3 3

    6 1 1

    6 3 4

    2 4 3

    5 6 3

    7 2 1

    【输出样例】

    7

    Dijkstra+优先队列优化:

    源代码:
    
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    struct Node
    {
        int To,S;
        Node(int t1,int t2) //似乎是强制类型转换。
        {
            To=t1;
            S=t2;
        }
        bool operator < (const Node &t) const //看来得背过了,重载运算符。
        {
            if (S==t.S)
              return To<t.To; //明显要快一点。
            else
              return S>t.S;
        }
    };
    priority_queue <Node> Q;
    vector <Node> Edge[2501];
    int m,n,Start,End,i[2501];
    void Dijkstra()
    {
        i[Start]=0;
        Q.push(Node(Start,i[Start]));
        while (!Q.empty())
        {
            Node t=Q.top();
            Q.pop();
            for (int a=0;a<Edge[t.To].size();a++)
            {
                Node T=Edge[t.To][a];
                if (i[T.To]>t.S+T.S)
                {
                    i[T.To]=t.S+T.S;
                    Q.push(Node(T.To,i[T.To])); //其实这才是更新,i[]不过是记录。
                }
            }
        }
    }
    int main() //Dijkstra+优先队列。
    {
        memset(i,0x3f,sizeof(i));
        scanf("%d%d%d%d",&n,&m,&Start,&End);
        for (int a=0;a<m;a++)
        {
            int t,t1,t2;
            scanf("%d%d%d",&t1,&t2,&t);
            Edge[t1].push_back(Node(t2,t));
            Edge[t2].push_back(Node(t1,t));
        }
        Dijkstra();
        printf("%d",i[End]);
        return 0;
    }

    SPFA+SLF优化:

    源代码:
    
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm> 
    using namespace std;
    struct Node1
    {
        int S,To,Next;
    }Edge[12401];
    struct Node2
    {
        int X,Y,S;
    }Map[12401];
    deque <int> Q; //双端队列。
    int m,n,Num(0),Start,End,i[2501],Sum[2501],Head[2501];
    bool In[2501]={0};
    void Add(int t1,int t2,int t)
    {
        Edge[++Num].To=t2;
        Edge[Num].S=t;
        Edge[Num].Next=Head[t1];
        Head[t1]=Num;
    }
    int main() //SPFA+SLF+随机化排序,妈的谁还能卡我!
    {
        memset(i,0x3f,sizeof(i));
        scanf("%d%d%d%d",&n,&m,&Start,&End);
        for (int a=0;a<m;a++)
          scanf("%d%d%d",&Map[a].X,&Map[a].Y,&Map[a].S);
        random_shuffle(Map,Map+m); //随机化排序。
        for (int a=0;a<m;a++)
        {
            Add(Map[a].X,Map[a].Y,Map[a].S);
            Add(Map[a].Y,Map[a].X,Map[a].S);
        }
        i[Start]=0;
        Q.push_back(Start);
        In[Start]=true;
        while (!Q.empty())
        {
            int t=Q.front();
            Q.pop_front();
            In[t]=false;
            for (int a=Head[t];a;a=Edge[a].Next)
            {
                int T=Edge[a].To;
                if (i[T]>i[t]+Edge[a].S)
                {
                    Sum[T]=Sum[t]+1;
                    if (Sum[T]>n) //判负环。
                      return 0;
                    i[T]=i[t]+Edge[a].S;
                    if (!In[T])
                    {
                        In[T]=true;
                        if (!Q.empty()&&i[Q.front()]>i[T])
                          Q.push_front(T);
                        else
                          Q.push_back(T);
                    }
                }
            }
        }
        printf("%d",i[End]);
        return 0;
    }
  • 相关阅读:
    python--随机生成汉字、数字
    PyCharm详细教程
    Struts2 笔记
    Servlet读取配置文件的三种方式
    Java笔记(十)
    Java笔记(九)
    Java笔记(八)
    Java笔记(七)
    Java笔记(六)
    Java笔记(五)
  • 原文地址:https://www.cnblogs.com/Ackermann/p/6023746.html
Copyright © 2011-2022 走看看