- 1000ms
- 262144K
description:
There are N cities in the country, and M directional roads from u to v(1≤u,v≤n). Every road has a distance ci. Haze is a Magical Girl that lives in City 1, she can choose no more than K roads and make their distances become 0. Now she wants to go to City N, please help her calculate the minimum distance.
Input
The first line has one integer T(1≤T≤5), then following T cases.
For each test case, the first line has three integers N,M and K.
Then the following M lines each line has three integers, describe a road, Ui,Vi,Ci. There might be multiple edges between u and v.
It is guaranteed that N≤100000,M≤200000,K≤10,
0 ≤Ci≤1e9. There is at least one path between City 1 and City N.
Output
For each test case, print the minimum distance.
样例输入:
1
5 6 1
1 2 2
1 3 4
2 4 3
3 4 1
3 5 6
4 5 2
样例输出:
3
题目来源:2018ACM-ICPC南京赛区预赛
题解思路:迪杰斯特拉最短路+dp分层图思想,将距离数组设置为dist[maxn][11],则dist[i][j]表示从起点开始到i节点,途中将j条路径免费的最短路距离。分层图又是什么意思呢?以免费路径相同的为一层,这样在松弛时可以选择是否让当前的边变为0,代码如下:
1.选择这条边不为0
if(d[e.to][lev]>d[u][lev]+e.dist)
{
d[e.to][lev]=d[u][lev]+e.dist;
Q.push(HeapNode(d[e.to][lev],lev*(n+1)+e.to));
}
2.选择这条边为0,进入下一层,,则dist[e.to][lev]变为dist[e.to][lev+1]因为多让一条边变为0
if(d[e.to][lev+1]>d[u][lev])
{
d[e.to][lev+1]=d[u][lev];
Q.push(HeapNode(d[e.to][lev+1],(lev+1)*(n+1)+e.to));
}
这样,全部代码就写出来了。
ps:分层图还是第一次碰到,图上dp也不会做,还得好好补补。
#include<bits/stdc++.h>
using namespace std;
#define e exp(1)
#define pi acos(-1)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define mem(a,b) memset(a,b,sizeof(a))
int gcd(int a,int b){return b?gcd(b,a%b):a;}
const int maxn=1e5+10;
int n,m,k,s,t;
struct qnode{
int v,dis,level;
qnode(int v=0,int dis=0,int level=0):v(v),dis(dis),level(level) {}
bool operator<(const qnode &r)const
{
return dis>r.dis;
}
};
struct Edge{
int v,w;
Edge(int v=0,int w=0):v(v),w(w) {}
};
vector<Edge> ve[maxn];
ll d[maxn][11];
bool vis[maxn][11];
void addEdge(int u,int v,int w)
{
ve[u].push_back(Edge(v,w));
}
void dijkstra(int start)
{
mem(vis,false);
mem(d,inf);
priority_queue<qnode> q;
d[start][0]=0;
q.push(qnode(start,0,0));
qnode tmp;
while(!q.empty())
{
tmp=q.top();
q.pop();
int u=tmp.v;
int lv=tmp.level;
if(vis[u][lv])continue;
vis[u][lv]=true;
for(int i=0; i<ve[u].size(); i++)
{
int v=ve[u][i].v;
int w=ve[u][i].w;
if(w+d[u][lv]<d[v][lv])
{
d[v][lv]=w+d[u][lv];
q.push(qnode(v,d[v][lv],lv));
}
if(lv<k)
{
if(d[u][lv]<d[v][lv+1])
{
d[v][lv+1]=d[u][lv];
q.push(qnode(v,d[v][lv+1],lv+1));
}
}
}
}
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&k))
{
scanf("%d%d",&s,&t);
for(int i=0; i<=n; i++)ve[i].clear();
for(int i=0; i<m; i++)
{
int u,v,w;scanf("%d%d%d",&u,&v,&w);
addEdge(u,v,w);
addEdge(v,u,w);
}
dijkstra(s);
ll ans=d[t][0];
for(int i=0; i<=k; i++)ans=min(ans,d[t][i]);
printf("%lld\n",ans);
}
return 0;
}