标签:多校
1 5 2 0 0 0 1 3 1 1 0 5 1 1 1 1 1
0 2 1 1 -1HintIf you need a larger stack size, please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.
题意:有n个点,排成一行,两个相邻点的距离为1,第 i 个点只能走相隔距离为 L[i]<=dis<=R[i],如果第 i 个点走到 第 j 个点花费为 cost[ i ],现在从1点开始,问能到的其他点 i 的最小花费为多少,不能到的点花费输出-1。
解题:因为每个点走到其他的点花费>=1,所以可以用SET 或 优先队列 按花费最小的点先取出,每个点只走一次。
//#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<set> using namespace std; const int N = 310000; #define ll __int64 struct NODE { int id; ll cost; friend bool operator < (NODE aa , NODE bb) { if(aa.cost==bb.cost) return aa.id<bb.id; return aa.cost<bb.cost; } }; set<NODE>node; set<int>id; ll C[N]; struct nnn { int l, r , cost; }man[N]; int main() { int T,n; NODE now , pre; scanf("%d",&T); while(T--) { scanf("%d",&n); memset(C,-1,sizeof(C)); for(int i=1; i<=n; i++) scanf("%d",&man[i].l); for(int i=1; i<=n; i++) scanf("%d",&man[i].r); for(int i=1; i<=n; i++) scanf("%d",&man[i].cost); node.clear(); id.clear(); for(int i=2; i<=n; i++) id.insert(i); C[1]=0; now.id=1; now.cost=man[1].cost; node.insert(now); set<int>::iterator it,it1; while(!node.empty()) { now=*node.begin(); node.erase(node.begin()); int L,R; L = now.id + man[now.id].l; R = now.id + man[now.id].r; it=id.lower_bound( L ); while(it!=id.end()&&*it<=R){ pre.id=*it; pre.cost= now.cost + man[ pre.id ].cost; node.insert( pre ); C[pre.id] = now.cost; it1 = it++; id.erase( it1 ); } L = now.id - man[now.id].r; R = now.id - man[now.id].l; it = id.lower_bound( L ); while(it!=id.end()&&*it<=R){ pre.id=*it; pre.cost = now.cost + man[ pre.id ].cost; node.insert( pre ); C[pre.id]=now.cost; it1=it++; id.erase( it1 ); } } for(int i=1; i<=n; i++) { if(i!=1)printf(" "); printf("%I64d",C[i]); } printf("\n"); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:多校
原文地址:http://blog.csdn.net/u010372095/article/details/47381753