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\n",ans);
105     }
106     return 0;
107 }

猜你喜欢

转载自www.cnblogs.com/iat14/p/11408298.html