ccf 2017 12 - 4 行车路线

附上代码:

#include<stdio.h>
#include<string.h>
#define inf 0x7fffffff
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int MAXM = 1e6 + 5;
int n, m;
typedef struct NODE
{
    int to;
    ll temp;
    ll cost;
    int ff;
    friend bool operator < (const NODE &a, const NODE &b) {
        return a.cost > b.cost;
    }
}node;
typedef struct Edge
{
    int from;///起点
    ll temp;///记录权值
    int f;///标记小路
    int next;
    int to;
    ll w;
} edge;
edge maps[MAXM];
int head[505];
ll dist[505];
int vids[505];
int cnt;
void creat ()
{
    for(int i=0; i<505; i++)
        head[i]=-1;
    cnt=0;
}
void add(int t,int u,int v,ll w)
{
    maps[cnt].f = t;
    maps[cnt].from = u;
    maps[cnt].to=v;
    maps[cnt].w=w;
    maps[cnt].next=head[u];///一开始放置为-1,-1的条件就可以跳出
    ///下一步接着储存,head[u]的值,就是前面的位置
    head[u]=cnt++;///head[u]会得到这条线的值
}
ll dijkstra(int s,int t)
{
    for(int i=0; i<505; i++)
    {
        vids[i]=0;
        dist[i]=inf;
    }
    priority_queue<node>que;
    node begins;
    begins.to = s;
    begins.temp = 0;
    begins.cost = 0;
    begins.ff = 0;
    que.push(begins);
    while(!que.empty())
    {
        node ends=que.top();
        que.pop();
        if(!vids[ends.to])
        {
            vids[ends.to]=1;
            dist[ends.to]=ends.cost;
            for(int i = head[ends.to]; ~i; i = maps[i].next)
            {
                int to = maps[i].to;
                ll w = maps[i].w;
                int flag = maps[i].f;
                if(!vids[to])
                {
                    node ans;
                    ans.to=to;
                    if(ends.ff == 0 && flag == 0)
                    {
                        ans.cost = ends.cost + w;
                        ans.ff = flag;
                        ans.temp = 0;
                    }
                    else if(ends.ff == 1 && flag == 0)
                    {
                        ans.cost = ends.cost + w;
                        ans.ff = flag;
                        ans.temp = 0;
                    }
                    else if(ends.ff == 1 && flag == 1)
                    {
                        ans.cost = ends.cost - (ends.temp * ends.temp) + (ends.temp + w) * (ends.temp + w);
                        ans.ff = flag;
                        ans.temp = ends.temp + w;
                    }
                    else if(ends.ff == 0 && flag == 1)
                    {
                        ans.cost = ends.cost + (w * w);
                        ans.ff = flag;
                        ans.temp = w;
                    }
                    que.push(ans);
                }
            }
        }
    }
    if(dist[t] == inf)
    {
        return -1;
    }
    else
    {
        return dist[t];
    }
}
int main()
{
   while(~scanf("%d%d",&n, &m))
   {
       creat();
       int t, a, b;
       long long c;
       for (int i = 0; i < m; i ++) {
           scanf("%d%d%d%lld",&t, &a, &b, &c);
           add(t, a, b, c);
           add(t, b, a, c);
       }
       ll re = dijkstra(1, n);
       printf("%lld\n",re);
   }
    return 0;
}

原文地址:https://www.cnblogs.com/qq136155330/p/9683000.html

时间: 2024-07-31 15:51:46

ccf 2017 12 - 4 行车路线的相关文章

ccf 201712-4 行车路线(70分)

ccf 201712-4 行车路线 解题思路: 首先Dijkstra是基于贪心算法的,即每一次作出的选择都具有贪心选择性.此题由于有"如果连续走小道,小明的疲劳值会快速增加,连续走s公里小明会增加s2的疲劳度."这种情况,所以不能使用Dijkstra算法. 这里使用Bellman-Ford算法 70分备份待修改: 1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int n,m;/

CCF 2017 09-02 公共钥匙盒

 CCF 2017 09-02 公共钥匙盒 1.用快速排序函数结合排序规则函数来给取放排序. 2.vector数组的强大功能. 1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 struct node{ 6 int num;//钥匙的编号 7 int start;//动作开始时间 8 int action;//动作的类型 0:放 1:取 9 nod

java一周学习记录(2017/12/2)

姓名:Danny                               日期:2017/12/2 任务 日期 听课 编程程序 阅读课本 准备考试 考试 周六加课 日统计 周日 周一 30 120 150 周二 50 140 190 周三 150 150 150 周四 180 180 周五 100 180 280 周六 480 480

2017.12.02【NOIP提高组】模拟赛A组

2017.12.02[NOIP提高组]模拟赛A组 T1 3555[GDKOI2014模拟]树的直径 T2 3542[清华集训2014]冒泡排序 T3 3486[NOIP2013模拟联考10]道路改建(rebuild) T1 树直径的一个性质,两棵树合并,形成新的树的直径的两个端点为原树中的四个端点之二. 可以用反证法证明.用此性质本题就变成了lca裸题了 Code #include<cstdio> #include<cstring> #include<cmath> #i

2017.12.09【NOIP提高组】模拟赛A组

2017.12.09[NOIP提高组]模拟赛A组 T1 3489. [NOIP2013模拟联考11]数列的GCD(gcd) T2 3500.[NOIP2013模拟联考15]物语(monogatari) T3 3501.[NOIP2013模拟联考15]消息传递(news) 吐槽:这次的题好像有点水啊,但最简单的第二题都给打挂啦!!(数组开小了) T1 本套题中最难的题.考虑dp 设f[i]是b[1],b[2]...b[N]的最大公约数的数目,g[i]是b[1],b[2]...b[N]的公约数的数目

2017.12.12 每日黑科技

[碧桂园信管中心] [资讯与趋势] 1.WISE2017新商业大会开幕? 新商业公司的特点则是创新带来的高成长,并不断突破边界.融合创新,比如出行的滴滴,吃饭的美团.做智能手机的小米,信息阅读的今日头条,这些公司不仅快速改变了我们的生活,而且都是在几年内就成长为百亿美金估值的公司.关注新商业大会. http://36kr.com/p/5107584.html 2.<企业家>杂志最佳作者: 2018 年 18 个值得观测的营销趋势 市场营销趋势正在发生急剧改变,它几乎影响着每个公司.要想使你的公

2017.12.03

2017.12.03 贪心 1.金银岛 思路:既然每一种金属都是可以任意切割的,那么就可以先求出每一种金属的单位价值,把它进行排序,从单位价值最大的开始装起,只要背包还有空间就全部装进背包,如果装不完就把剩下的空间全部装这种物体. for(i=1;i<=s;i++){ scanf("%lf%lf",&gold[i][1],&gold[i][2]); gold[i][3]=gold[i][2]/gold[i][1]; } for(i=1;i<s;i++){ i

2017.12.17

2017.12.03 贪心,分治综合习题(1) 1. 2的幂次方表示 思路:本题很容易就想到用递归做.对于2的一次和二次,可以直接打表输出,而且题中所给的数据不大,N<20000,可以预处理把21到215储存在一个数组里,以后好比较.然后就贪心调用函数,把k每次从大到小比较,用s记数,输出括号,进行下一次递归.需要注意的是,在递归中,2的零次幂和2的一次幂是要单独特殊判断的. 核心代码: if(k==0){ printf("0"); return; } else if(k==1)

2017.12.18 2周1次课

2017.12.18 二周第一次课 2.6 相对和绝对路径 什么是一个文件的路径呢 简单地说,就是这个文件存放的地方.只要你告诉系统某个文件的路径,系统就可以找到这个文件 Linux中,存在着绝对路径和相对路径. 绝对路径:路径一定是由根目录"/"开头的,不管在哪个目录下,都能通过绝对路径找到这个文件. 相对路径 :是你所在位置的路径,以当前目录开头的. 查看当前目录的路径,使用命令[pwd] ".ssh/authorized_keys"就是相对路径,相对"