题意:给出起点和终点,然后有k次机会使得路径上的某些路径的值减半,问从起点到终点的最小花费
思路:很明显的分层图最短路嘛,自己也没有去研究算法的含义,队友和我说就是将图分成了n层,然后将这个可以减半的费用连接这n层,然后跑个类似的最短了就可以了,今天改了一个模版,改成了自己喜欢的风格,明天在做几道分层图在看看概念把,这题就是个模版题
#include <queue>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=10010;
struct edge{
int to,cost;
edge(int a,int b){to=a;cost=b;}
};
vector<edge>G[maxn];
int vis[maxn],dis[maxn],n,m,k;
int dijkstra(int s,int t){
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
priority_queue<P, vector<P>, greater<P> >que;
dis[s]=0;que.push(P(0,s));
while (!que.empty()){
P p=que.top();que.pop();
int v=p.second;
if (vis[v]) continue;
vis[v]=1;
for(int i=0;i<G[v].size();i++){
edge e=G[v][i];
if(dis[v]+e.cost<dis[e.to]){
dis[e.to]=dis[v]+e.cost;
que.push(P(dis[e.to],e.to));
}
}
}
int ans=inf;
for(int i=0;i<=k;i++)
ans=min(ans,dis[i*n+t]);
if(ans==inf) return -1;
return ans;
}
int U[maxn],V[maxn],COST[maxn],num[110][110];
int main(){
int st,en;
while(scanf("%d%d%d",&st,&en,&k)!=-1){
for(int i=0;i<maxn;i++) G[i].clear();
st++;en++;
n=max(st,en);
scanf("%d",&m);
memset(num,inf,sizeof(num));
for(int i=1;i<=m;i++){
scanf("%d%d%d",&U[i],&V[i],&COST[i]);
U[i]++;V[i]++;num[U[i]][V[i]]=min(COST[i],num[U[i]][V[i]]);
n=max(n,max(U[i],V[i]));
}
for(int i=1;i<=m;i++){
for(int j=0;j<=k;j++){
G[j*n+U[i]].push_back(edge(j*n+V[i],num[U[i]][V[i]]));
if(j<k) G[j*n+U[i]].push_back(edge((j+1)*n+V[i],num[U[i]][V[i]]/2));
}
}
int ans=dijkstra(st,en);
if(ans==-1) printf("KengDie\n");
else printf("%d\n",ans);
}
return 0;
}