zoukankan      html  css  js  c++  java
  • hdu 6714 最短路 2 floyd dijkstra

    至少得知道floyd的最初形式,dp[k][i][j],只经过前k个点,i到j的最短路。

    所以题目就是问你,任意两点间的最短路,经过的最大编号的点最小是多少,还不含两个端点。

    魔改一下dijkstra就行了,每个点跑一次。先比较长度,长度相同比较下最大编号谁的更小。每个点存的经过最大编号并不包含这个点本身。记得特判下起点终点直连的情况。

      1 #include <cstdio>
      2 #include <queue> 
      3 using namespace std;
      4 typedef long long ll;
      5 const int mo = 998244353,MAXN = 1010,MAXM = 4010;
      6 const ll inf = 1e14;
      7 struct pot
      8 {
      9     int x,maxn;
     10     ll dis;
     11     pot (int _x = 0,ll _dis = 0,int _maxn = 0) : x(_x),dis(_dis),maxn(_maxn) {}
     12     friend bool operator < (pot a,pot b)
     13     {
     14         if (a.dis != b.dis)
     15             return a.dis > b.dis;
     16         return a.maxn > b.maxn;
     17     }
     18 };
     19 struct dat
     20 {
     21     int maxn;
     22     ll dis;
     23     dat (ll _dis = 0,int _maxn = 0) : dis(_dis),maxn(_maxn) {}
     24     friend bool operator < (dat a,dat b)
     25     {
     26         if (a.dis != b.dis)
     27             return a.dis > b.dis;
     28         return a.maxn > b.maxn;
     29     }
     30 };
     31 priority_queue <pot> que;
     32 dat dis[MAXN];
     33 int head[MAXN],to[MAXM],nxt[MAXM],val[MAXM];
     34 int T,n,m,cnt,ans;
     35 bool vis[MAXN];
     36 void add(int x,int y,int v)
     37 {
     38     nxt[++cnt] = head[x];
     39     to[cnt] = y;
     40     head[x] = cnt;
     41     val[cnt] = v;
     42 }
     43 void dijkstra(int s)
     44 {
     45     for (int i = 1;i <= n;i++)
     46     {
     47         dis[i] = dat(inf,0);
     48         vis[i] = false;
     49     }
     50     que.push(pot(s,0,0));
     51     dis[s] = dat(0,0);
     52     while(que.empty() == false)
     53     {
     54         pot now = que.top();
     55         que.pop();
     56         if(vis[now.x] == true) 
     57             continue;
     58         vis[now.x] = true;
     59         for(int i = head[now.x]; i; i = nxt[i])
     60         {
     61             if (now.x != s)
     62             {
     63                 if(dis[to[i]].dis > dis[now.x].dis + val[i] || (dis[to[i]].dis == dis[now.x].dis + val[i]) && (max(dis[now.x].maxn,now.x) < dis[to[i]].maxn))
     64                 {
     65                     dis[to[i]].dis = dis[now.x].dis + val[i];
     66                     dis[to[i]].maxn = max(dis[now.x].maxn,now.x);
     67                     que.push(pot(to[i],dis[to[i]].dis,dis[to[i]].maxn));
     68                 }
     69             }else
     70             {
     71                 if(dis[to[i]].dis >= dis[now.x].dis + val[i])
     72                 {
     73                     dis[to[i]].dis = dis[now.x].dis + val[i];
     74                     dis[to[i]].maxn = 0;
     75                     que.push(pot(to[i],dis[to[i]].dis,dis[to[i]].maxn));
     76                 }
     77             }
     78         }
     79     }
     80 }
     81 int main()
     82 {
     83     for (scanf("%d",&T);T != 0;T--)
     84     {
     85         for (int i = 1;i <= cnt;i++)
     86             nxt[i] = 0;
     87         for (int i = 1;i <= n;i++)
     88             head[i] = 0;
     89         cnt = ans = 0;
     90         scanf("%d%d",&n,&m);
     91         int tx,ty,tv;
     92         for (int i = 1;i <= m;i++)
     93         {
     94             scanf("%d%d%d",&tx,&ty,&tv);
     95             add(tx,ty,tv);
     96             add(ty,tx,tv);
     97         }
     98         for (int i = 1;i <= n;i++)
     99         {
    100             dijkstra(i);
    101             for (int j = 1;j <= n;j++)
    102                 ans = ((ll)ans + dis[j].maxn) % mo;
    103         }
    104         printf("%d
    ",ans);
    105     }
    106     return 0;
    107 }
    心之所动 且就随缘去吧
  • 相关阅读:
    div+css简写原则
    并发控制
    div+css之块级元素与内联元素
    window.event对象属性(转)
    SQL SERVER 架构管理
    关系的规范化
    js常用事件
    物联小白CoAP协议
    图片不停的横滚
    DropDownlist编程问题
  • 原文地址:https://www.cnblogs.com/iat14/p/11408298.html
Copyright © 2011-2022 走看看