示例:
输入:
3 2 1 3 1
1 2 1
2 3 2
输出:1
题意:求s,t最短路,可将k条边权值置零。
题解:分层图最短路原题
#include<bits/stdc++.h> using namespace std; typedef long long int ll; const int maxn = 1e5+10; const int INF = 0x3f3f3f3f; struct State { // 优先队列的结点结构体 int v, w, cnt; // cnt 表示已经使用多少次免费通行权限 State() {} State(int v, int w, int cnt) : v(v), w(w), cnt(cnt) {} bool operator<(const State &rhs) const { return w > rhs.w; } }; struct node { int v; int w; int next; /* data */ } edge[maxn]; priority_queue<State>pq; int n,t,m,k,u,v,w,s; int cnt; bool vis[maxn][20]; int dis[maxn][20]; int head[maxn]; void add(int u,int v,int w) //链式前向星存边 { edge[cnt] = {v,w,head[u]}; head[u] = cnt++; } void dijkstra() { memset(dis, 0x3f, sizeof(dis)); dis[s][0] = 0; pq.push(State(s, 0, 0)); // 到起点不需要使用免费通行权,距离为零 while (!pq.empty()) { State top = pq.top(); pq.pop(); int u = top.v; int nowCnt = top.cnt; if (vis[u][nowCnt]) continue; vis[u][nowCnt] = true; for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].v, w = edge[i].w; if (nowCnt < k && dis[v][nowCnt + 1] > dis[u][nowCnt]) { // 可以免费通行 dis[v][nowCnt + 1] = dis[u][nowCnt]; pq.push(State(v, dis[v][nowCnt + 1], nowCnt + 1)); } if (dis[v][nowCnt] > dis[u][nowCnt] + w) { // 不可以免费通行 dis[v][nowCnt] = dis[u][nowCnt] + w; pq.push(State(v, dis[v][nowCnt], nowCnt)); } } } } int main() { memset(head,-1,sizeof (head)); scanf("%d%d%d%d%d",&n,&m,&s,&t,&k); while (m--) { scanf("%d%d%d",&u,&v,&w); add(u, v, w); add(v, u, w); } int ans = INF; dijkstra(); for (int i = 0; i <= k; ++i) ans = min(ans, dis[t][i]); // 对到达终点的所有情况取最优值 cout << ans << endl; }