[codeforces229B]星球

来源:互联网 发布:淘宝怎么入驻全球购 编辑:程序博客网 时间:2024/06/09 22:43

大致题意:有n个星球,m条双向通道。

初始在1号点,要到达n号点,在某些时刻到达会有其他人到达需要等待至没有其他人到达的第1s才能走

SB题……map set vector乱搞一下  Tutorial说复杂度是(n+m)logn+sigmak 然后我写了个nmlogn的被神hack数据卡掉了 不知道当时hack了多少人

要我搞个数据我就出张网格图 反正这题时限1s估计能卡掉不少spfa

附带pbds的配对堆+set乱搞版本

#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#include<cstring>#include<queue>#include<stack>#include<map>#include<cmath>#include<set>#include<ext/pb_ds/priority_queue.hpp>using namespace std;typedef pair<int,int> pii;using namespace __gnu_pbds;const int INF = 0x7fffff7f;int n,m;__gnu_pbds::priority_queue<pii,greater<pii>,pairing_heap_tag > q;__gnu_pbds::priority_queue<pii,greater<pii>,pairing_heap_tag >::point_iterator it[100001];struct edge{int from,to,val,pre;}Edge[200010];int dis[100002];set<int> s[100002];inline int init(){int now=0;char c;bool flag=false;while(1){c=getchar();if(c>='0'&&c<='9'){now=now*10+c-'0';flag=true;}else if(flag)return now;}}int cnt=0,head[100002];bool vis[100002];inline void addedge(int from,int to,int val){++cnt;Edge[cnt]=((edge){from,to,val,head[from]});head[from]=cnt;}inline void dijkstra(){pii now,o;dis[1]=0;while(s[1].count(dis[1])!=0){dis[1]++;}it[1]=q.push(make_pair(dis[1],1));while(!q.empty()){now=q.top();q.pop();if(vis[now.second])continue;vis[now.second]=true;if(now.second==n)break;while(s[now.second].count(now.first)){now.first++;}for(int j=head[now.second];j;j=Edge[j].pre){if(!vis[Edge[j].to]&&dis[Edge[j].to]>now.first+Edge[j].val){dis[Edge[j].to]=now.first+Edge[j].val;if(it[Edge[j].to]!=0){q.modify(it[Edge[j].to],make_pair(dis[Edge[j].to],Edge[j].to));}else it[Edge[j].to]=q.push(make_pair(dis[Edge[j].to],Edge[j].to));}}}}int main(){int a,b,c;scanf("%d %d",&n,&m);for(int i=1;i<=m;i++){scanf("%d %d %d",&a,&b,&c);addedge(a,b,c);addedge(b,a,c);}int k;int x;for(int i=1;i<=n;i++){dis[i]=INF;scanf("%d",&k);x=0;for(int j=1;j<=k;j++){scanf("%d",&x);s[i].insert(x);}}dijkstra();if(dis[n]!=INF){printf("%d\n",dis[n]);}else printf("-1\n");return 0;}


0 0