2017 Multi-University Training Contest 10 1011 Two Paths HDU 6181 (次短路)

来源:互联网 发布:windows日志查询 编辑:程序博客网 时间:2024/06/06 11:38

题意:给你一个有向图,问你他的次短路长度(与最短路至少有一条边不同即可)


思路:如果最短路有多条,那答案就是最短路,否则就是次短路


求次短路(见点击打开链接):

  1.     思路: 
  2.         把求最短路时更新最短路的那部分改一下。 
  3.         dis1,dis2数组分别记录到该点的最短路和次短路 
  4.         分三种情况: 
  5.             1.若该点最短路+下一条边比到下个点的最短路短,则更新下个点的最短路,同时更新次短路为原最短路 
  6.             2.若该点次短路+下一条边比到下个点的次短路短,则更新下个点的次短路 
  7.             3.若该点最短路+下一条边比到下个点的最短路长同时比下个点的次短路短,则更新下个点的次短路 

代码:

#include<iostream>#include<cstdio>#include<queue>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const int maxn = 2e5+5;const ll INF = 0x3f3f3f3f3f3f3f3f;int n, m, k, head[maxn];ll cnt[maxn];ll dis1[maxn], dis2[maxn], dis[maxn];bool book[maxn];struct node{    int v, w, next;}edge[maxn];void addEdge(int u, int v, int w){    edge[k].v = v;    edge[k].w = w;    edge[k].next = head[u];    head[u] = k++;}void spfa(int u){    for(int i = 1; i <= n; i++) dis1[i] = INF;    for(int i = 1; i <= n; i++) dis2[i] = INF;    memset(book, 0, sizeof(book));    queue<int> q;    q.push(u);    dis1[u] = 0;    book[u] = 1;    while(!q.empty())    {        u = q.front(); q.pop();        book[u] = 0;        for(int i = head[u]; i != -1; i = edge[i].next)        {            int v = edge[i].v;            int w = edge[i].w;            if(dis1[v] > dis1[u]+w)            {                dis2[v] = dis1[v];                dis1[v] = dis1[u]+w;                if(!book[v]) book[v] = 1, q.push(v);            }            if(dis2[v] > dis2[u]+w)            {                dis2[v] = dis2[u]+w;                if(!book[v]) book[v] = 1, q.push(v);            }            if(dis1[v] < dis1[u]+w && dis2[v] > dis1[u]+w)            {                dis2[v] = dis1[u]+w;                if(!book[v]) book[v] = 1, q.push(v);            }        }    }}void spfa2(int u){    for(int i = 1; i <= n; i++) dis[i] = INF;    memset(book, 0, sizeof(book));    queue<int> q;    q.push(u);    book[u] = cnt[u] = 1;    dis[u] = 0;    while(!q.empty())    {        u = q.front(); q.pop();        book[u] = 0;        for(int i = head[u]; i != -1; i = edge[i].next)        {            int v = edge[i].v;            int w = edge[i].w;            if(dis[u]+w < dis[v])            {                dis[v] = dis[u]+w;                if(!book[v]) book[v] = 1, q.push(v);                cnt[v] = cnt[u];            }            else if(dis[u]+w == dis[v])            {                cnt[v] += cnt[u];            }        }    }}int main(void){    int t;    cin >> t;    while(t--)    {        k = 0;        memset(cnt, 0, sizeof(cnt));        memset(head, -1, sizeof(head));        scanf("%d%d", &n, &m);        for(int i = 1; i <= m; i++)        {            int u, v, w;            scanf("%d%d%d", &u, &v, &w);            addEdge(u, v, w);            addEdge(v, u, w);        }        spfa(1);        spfa2(1);        if(cnt[n] > 1) printf("%lld\n", dis1[n]);        else printf("%lld\n", dis2[n]);    }    return 0;}




阅读全文
1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 光大普卡额度4万封顶了怎么办 天天特价通过后价格设置错误怎么办 苏宁易购不小心点了免密支付怎么办 别人知道自己京东的账号密码怎么办 oppo手机刷机要锁屏密码怎么办 在苏宁易购退款成功又收到货怎么办 今日头条转发出现未安装微信怎么办 打开手机后自动弹出广告怎么办去除 朋友圈发广告被腾讯屏蔽了怎么办 新商盟手机订烟登录密码忘了怎么办 手机版战神斯巴达幽灵经常崩怎么办 代购买的东西被海关扣了怎么办 托朋友代购给了钱联系不上人怎么办 签了合同被加盟商骗了怎么办 百度云盘下载时本地空间不足怎么办 百度云盘隐私空间没密码忘了怎么办 华为云空间的帐号密码忘记了怎么办 快递被快递公司弄丢了怎么办 快递到了人不在那个地方了怎么办 微信被骗了1千多怎么办 客户货已经用啦要求退款退货怎么办 网购收到别人退货的东西怎么办 好省输入订单编号查不到订单怎么办 快递没有当面验收后发现损坏怎么办 支付宝电脑付款风控异常怎么办 京东买东西地址填错了怎么办 商场卖的衣服跟官网差价大怎么办 网购的衣服有好几个破洞怎么办 出租发票有牌号是假的怎么办 支付宝里的多收多保被降级了怎么办 超市购物卡余额与实际不符怎么办 发广告的公众号无法取消关注怎么办 扣扣需要手机验证码登录怎么办 驾校报了联系不了教练了怎么办 手机号被别人注册了百度网盘怎么办 注册公司云证书申请成功后怎么办 淘宝购物卖家迟迟不发货怎么办 淘宝直播顾客加购物车不下单怎么办 东方航空联程机票航班延误怎么办 别别人伸请更换手机绑定qq怎么办 绑定手机号的扣扣忘记密码怎么办