标签:lin ++i ffffff 信息 5* 分层 txt 这不 int
https://www.luogu.org/problem/P4822
现在这个大陆上有 N 个城市,M 条双向的道路。城市编号为 1~N,我们在 1 号城市,需要到 N 号城市,怎样才能最快地到达呢?
这不就是最短路问题吗?我们都知道可以用 Dijkstra、Bellman-Ford、Floyd-Warshall等算法来解决。
现在,我们一共有 K 张可以使时间变慢 50%的 SpellCard,也就是说,在通过某条路径时,我们可以选择使用一张卡片,这样,我们通过这一条道路的时间 就可以减少到原先的一半。需要注意的是:
给定以上的信息,你的任务是:求出在可以使用这不超过 K 张时间减速的 SpellCard 之情形下,从城市1 到城市N最少需要多长时间。
分层图,就是只能往下一层走,不能走会从前走过的层
分层图建好了就直接最短路啦
#include<iostream> #include<cstdio> #include<cstring> #define ri register int #define u int #define NN 55*105 #define MM 1005*105 namespace fast { inline u in() { u x(0); char s=getchar(); while(s<‘0‘||s>‘9‘) { s=getchar(); } while(s>=‘0‘&&s<=‘9‘) { x=(x<<1)+(x<<3)+s-‘0‘; s=getchar(); } return x; } } using fast::in; namespace all { u cnt,N,M,K,h[NN]; struct node { u to,next,va; } a[MM<<1]; inline void add(const u &x,const u &y,const u &z) { a[++cnt].next=h[x],a[cnt].to=y,a[cnt].va=z,h[x]=cnt; } u d[NN],vt[NN],q[1000005]; struct node1{ u x,y,z; }b[MM]; u run(const u &x,const u &n) { ri l(0),r(0),k; for(ri i(1);i<=n;++i) d[i]=0x7fffffff; d[x]=0,q[++r]=x; while(l<r) { k=q[++l],vt[k]=0; for(ri i=h[k]; i; i=a[i].next) { u y=a[i].to,z=a[i].va; if(d[k]+z<d[y]) { d[y]=d[k]+z; if(!vt[y]) { vt[y]=1,q[++r]=y; } } } } } inline void solve(){ N=in(),M=in(),K=in(); for(ri i(1);i<=M;++i){ u _a(in()),_b(in()),_c(in()); b[i].x=_a,b[i].y=_b,b[i].z=_c; } for(ri i(1);i<=K;++i){//建1-k层,普遍性地用循环建 for(ri j(1);j<=M;++j){ u _a(b[j].x+(i-1)*N),_b(b[j].y+(i-1)*N),_c(b[j].z); add(_a,_b,_c),add(_b,_a,_c);//本层 add(_a,_b+N,_c/2),add(_b,_a+N,_c/2);//通往下一层 } } for(ri i(K+1);i<=K+1;++i){//建第k+1层,因为不想第1-k层还有下一层,所以单独来建 for(ri j(1);j<=M;++j){ u _a(b[j].x+(i-1)*N),_b(b[j].y+(i-1)*N),_c(b[j].z); add(_a,_b,_c),add(_b,_a,_c);//只有本层 } } run(1,N*(K+1));//共k+1层, N*(K+1)个点 u ans(0x7fffffff); for(ri i(1);i<=K+1;++i){ ans=std::min(d[N+(i-1)*N],ans);//所有层的第N点都是可以的 } printf("%d",ans); } } int main() { //freopen("x.txt","r",stdin); all::solve(); }
标签:lin ++i ffffff 信息 5* 分层 txt 这不 int
原文地址:https://www.cnblogs.com/ling-zhi/p/11620491.html