题意:
有向图,可以把k条路的长度变为0,求1到n的最短路
思路:
将图复制k份,一共k+1层图,对于每一条i→j,都连一条低层的i→高层的j,并且权值为0
即对每一对<i,j,w>,都加边<i,j,w>,<i+n,j+n,w>,<i+2n,j+2n,w>,....,<i+kn,j+kn,w>
同时加“楼梯”<i,j+n,0>,<i+n,j+2n,0>,...,<i+(k-1)n, j+kn>
然后跑一个1~(k+1)n的最短路,用迪杰斯特拉+堆优化
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<set> #include<vector> #include<map> #include<functional> #define fst first #define sc second #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define rc root<<1|1 #define lowbit(x) ((x)&(-x)) using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const db eps = 1e-6; const int mod = 1e9+7; const int maxn = 2e6+1000; const int maxm = 2e6+100; const int inf = 0x3f3f3f3f; const db pi = acos(-1.0); int dist[maxn]; struct node{ int id, d; node(){} node(int a,int b) {id = a; d = b;} bool operator < (const node & a)const{ if(d == a.d) return id > a.id; else return d > a.d; } }; vector<node>e[maxn]; int n; void dijkstra(int s){ for(int i = 0; i <= n; i++) dist[i] = inf; dist[s] = 0; priority_queue<node>q; q.push(node(s, dist[s])); while(!q.empty()){ node top = q.top(); q.pop(); if(top.d != dist[top.id]) continue; for(int i = 0; i < (int)e[top.id].size(); i++){ node x = e[top.id][i]; if(dist[x.id] > top.d + x.d){ dist[x.id] = top.d + x.d; q.push(node(x.id, dist[x.id])); } } } return; } int main() { int T; scanf("%d", &T); while(T--){ int m, k; scanf("%d %d %d", &n, &m, &k); while(m--){ int x ,y, w; scanf("%d %d %d", &x, &y, &w); for(int i = 0; i <= k; i++){ e[x + i*n].pb(node(y + i*n, w)); if(i)e[x + (i-1)*n].pb(node(y + i*n, 0)); } } n += k*n; dijkstra(1); printf("%d\n", dist[n]); for(int i = 0; i <= n; i++)e[i].clear(); } return 0; }
原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/9582016.html
时间: 2024-10-09 08:16:47