思路
诸如此类带路径使用次数有限制的题貌似都是要用到分层图来解决的问题
通过把一张图分成k层相等的图
这样当跑完dij后
对于每一层图的终点来说
意义就是:使用了 i 次免费路径到达终点时花费的最小值
基本建图方法:
对于道路的两个端点
①在每一层上把这两个点连起来,费用为w
②把每层之间的这两个点连起来,费用为0
跑完最大流枚举每层的终点找最小值即可
CODE

1 #include <bits/stdc++.h> 2 #define dbg(x) cout << #x << "=" << x << endl 3 #define eps 1e-8 4 #define pi acos(-1.0) 5 6 using namespace std; 7 typedef long long LL; 8 9 template<class T>inline void read(T &res) 10 { 11 char c;T flag=1; 12 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 13 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 14 } 15 16 namespace _buff { 17 const size_t BUFF = 1 << 19; 18 char ibuf[BUFF], *ib = ibuf, *ie = ibuf; 19 char getc() { 20 if (ib == ie) { 21 ib = ibuf; 22 ie = ibuf + fread(ibuf, 1, BUFF, stdin); 23 } 24 return ib == ie ? -1 : *ib++; 25 } 26 } 27 28 int qread() { 29 using namespace _buff; 30 int ret = 0; 31 bool pos = true; 32 char c = getc(); 33 for (; (c < '0' || c > '9') && c != '-'; c = getc()) { 34 assert(~c); 35 } 36 if (c == '-') { 37 pos = false; 38 c = getc(); 39 } 40 for (; c >= '0' && c <= '9'; c = getc()) { 41 ret = (ret << 3) + (ret << 1) + (c ^ 48); 42 } 43 return pos ? ret : -ret; 44 } 45 46 const int maxn = 2e5 + 7; 47 const int inf = 0x3f3f3f3f; 48 49 int head[maxn << 1], edge[maxn << 1], w[maxn << 1], nxt[maxn << 1]; 50 int cnt; 51 52 inline void BuildGraph (int u, int v, int c) { 53 cnt++; 54 edge[cnt] = v; 55 nxt[cnt] = head[u]; 56 w[cnt] = c; 57 head[u] = cnt; 58 } 59 60 struct node { 61 int u,v; 62 bool operator <(const node &t) const { 63 return u > t.u; 64 } 65 }; 66 67 int n,m,s,t,k; 68 int dis[maxn]; 69 bool vis[maxn << 1]; 70 71 priority_queue < node > q; 72 73 void dijkstra(int s) { 74 memset(dis, 0x3f, sizeof(dis)); 75 dis[s] = 0; 76 node temp; 77 temp.u = 0; 78 temp.v = s; 79 q.push(temp); 80 while(!q.empty()) { 81 int u = q.top().v; 82 int d = q.top().u; 83 q.pop(); 84 if(vis[u]) continue; 85 vis[u] = true; 86 for (int i = head[u]; i; i = nxt[i]) { 87 int v = edge[i]; 88 int c = w[i]; 89 if(dis[v] > dis[u] + c) { 90 dis[v] = dis[u] + c; 91 node p; 92 p.u = dis[v], p.v = v; 93 q.push(p); 94 } 95 } 96 } 97 } 98 99 int main() 100 { 101 read(n); read(m); read(k); 102 read(s); read(t); 103 ++s, ++t; 104 int u, v, w; 105 for ( int i = 1; i <= m; ++i ) { 106 read(u); read(v); read(w); 107 ++u, ++v; 108 BuildGraph(u, v, w); 109 BuildGraph(v, u, w); 110 for ( int j = 1; j <= k; ++j ) { 111 BuildGraph(u + (j - 1) * n, v + j * n, 0); 112 BuildGraph(v + (j - 1) * n, u + j * n, 0); 113 BuildGraph(u + j * n, v + j * n, w); 114 BuildGraph(v + j * n, u + j * n, w); 115 } 116 } 117 dijkstra(s); 118 int ans = INT_MAX; 119 for ( int i = 0; i <= k; ++i ) { 120 ans = min(ans, dis[t + i * n]); 121 //printf("dis[%d]:%d ",t + i * n, dis[t + i * n]); 122 } 123 cout << ans << endl; 124 return 0; 125 }