题解 P4568 【[JLOI2011]飞行路线】
有兴趣的童鞋可以去刷这道题
双倍经验
原题link
Dijkstra+dp(?)
附样例图片,使用EternalAlexander的OI painter
(我是先多建边)
dijkstra,删掉vis数组,dp即可
dist[i][j]为点i用掉j次免费机会时到源点的最短路
剩下的很好理解?(雾)
#include<bits/stdc++.h>
using namespace std;
int n,m,K;
int ip1,ip2,ip3,st,en;
int dist[10010][11];
struct edge
{
int to;
int dis;
int N;
};
struct node
{
int dis;
int pos,N;
bool operator < (const node &x)const
{
return x.dis<dis;
}
};
vector<edge>a[10010];
void Dijkstra(int x)
{
priority_queue<node>q;
for(int i=0;i<=1;i++)
{
node sta;
sta.dis=0;
sta.pos=x;
sta.N=i;
dist[x][i]=0;
q.push(sta);
}
while(!q.empty())
{
node T=q.top();
q.pop();
int now=T.pos;
for(int i=0;i<a[now].size();i++)
{
if(a[now][i].N+T.N>K)
{
continue;
}
if(dist[a[now][i].to][T.N+a[now][i].N]>dist[now][T.N]+a[now][i].dis)
{
dist[a[now][i].to][T.N+a[now][i].N]=dist[now][T.N]+a[now][i].dis;
node tmp;
tmp.dis=dist[a[now][i].to][T.N+a[now][i].N];
tmp.pos=a[now][i].to;
tmp.N=T.N+a[now][i].N;
q.push(tmp);
}
}
}
}
int main()
{
cin>>n>>m>>K;
cin>>st>>en;
for(int i=1;i<=m;i++)
{
cin>>ip1>>ip2>>ip3;
a[ip1].push_back((edge){ip2,ip3,0});
a[ip2].push_back((edge){ip1,ip3,0});
a[ip1].push_back((edge){ip2,0,1});
a[ip2].push_back((edge){ip1,0,1});
}
for(int i=0;i<=10001;i++)
{
for(int j=0;j<=10;j++)
{
dist[i][j]=2147483647;
}
}
Dijkstra(st);
printf("%d",dist[en][K]);
}