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 }
心之所动 且就随缘去吧