标签:cst vector span ati 实现 cli == 迪杰斯特拉 color
大陆争 爸 霸这道题非常的玄学。
具体思路是这样的:看看每个守护某个门的结界最快什么时候能被炸掉。反正机器人不要钱,有无限个。你不如没走一步带无穷个机器人。然后霸这些值和到达某个门的最短路取个max就可以啦。
实现是跑一边迪杰斯特拉,跑的时候顺便更新这些玩意。
具体代码实现:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<climits> #define int long long #define maxa 8005 using namespace std; void read(int &x){ x=0; int f=1; char c=getchar(); while(c<‘0‘||c>‘9‘){ if(c==‘-‘)f=-1; c=getchar(); } while(c<=‘9‘&&c>=‘0‘){ x=((x<<1)+(x<<3))+c-‘0‘; c=getchar(); } x*=f; return ; } int n,m; int l[maxa]; vector <int> a[maxa]; int to[maxa*20],nxt[maxa*20],h[maxa],top,val[maxa*20]; void psh(int u,int v,int va){ to[++top]=v,nxt[top]=h[u],h[u]=top,val[top]=va; return ; } int d1[maxa],d2[maxa],c[maxa]; bool vis[maxa]; void AC_DREAM(){ priority_queue<pair <int,int> ,vector<pair <int,int> >,greater<pair <int,int> > >q; for(int i=1;i<=n;i++)d1[i]=INT_MAX; q.push(make_pair(0,1)); d1[1]=0; while(!q.empty()){ int now=q.top().second;q.pop(); if(vis[now])continue; vis[now]=1; int mx=max(d1[now],d2[now]); for(int i=h[now];i;i=nxt[i]){ int y=to[i]; if(mx+val[i]<d1[y]){ d1[y]=mx+val[i]; int tmp=max(d1[y],d2[y]); if(!c[y])q.push(make_pair(tmp,y)); } } for(int i=0,t;i<l[now];i++){ t=a[now][i]; c[t]--;d2[t]=max(d2[t],mx); int tmp=max(d1[t],d2[t]); if(!c[t])q.push(make_pair(tmp,t)); } } return ; } #undef int int main(){ #define int long long read(n),read(m); for(int i=1,u,v,va;i<=m;i++){ read(u),read(v),read(va); if(u!=v)psh(u,v,va); } for(int i=1,x;i<=n;i++){ read(c[i]); for(int j=1;j<=c[i];j++){ read(x); l[x]++; a[x].push_back(i); } } AC_DREAM(); cout<<max(d1[n],d2[n]); }
然后你就A了这道毒瘤签到题啦!
标签:cst vector span ati 实现 cli == 迪杰斯特拉 color
原文地址:https://www.cnblogs.com/WQT-FFT/p/11406452.html