标签:
题意:给出起点和终点,然后有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; }
标签:
原文地址:http://blog.csdn.net/dan__ge/article/details/51702663