1 条题解

  • 0
    @ 2025-8-24 21:36:28

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Feyn
    AFO

    搬运于2025-08-24 21:36:28,当前版本为作者最后更新于2022-07-06 14:25:11,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    link & 博客园食用

    这种做法需要吸氧才能通过,不是正解,所以只是提供一种题解区还没有的思路。

    可以用分层图的思路来做这道题。每次从一个方格转移到另一个方格时时间都发生了改变,时间的改变可以看成是不同层次的图之间的转移,所以只需要按照题意在相邻的两层图之间连边跑最短路即可。显然假如所有方块的周期的最小公倍数是 lcmlcm ,那么所有位置相同、时间模这个公倍数相同的状态在转移上是完全一样的,可以看成是同一个状态,所以第 lcm1lcm-1 层图应该向第 00 层图连边。其它有些细节比如建立超级源点(它可以一直呆在最开始节点上不出去)和超级汇点方便敲代码就是分层图的基本操作了。

    #include<bits/stdc++.h>
    //#define feyn
    #define p(a,b) (a*(m+2)+b+2)
    const int N=3000010;
    const int M=1010;
    const int R=12;
    using namespace std;
    inline void read(int &wh){
    	wh=0;int f=1;char w=getchar();
    	while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    	while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    	wh*=f;return;
    }
    
    inline int gcd(int s1,int s2){
    	return s2==0?s1:gcd(s2,s1%s2);
    }
    inline int lcm(int s1,int s2){
    	return s1*s2/gcd(s1,s2);
    }
    
    int m,lc=1,num[M],a[M][R];
    
    struct edge{
    	int t,v,next;
    }e[N*3];
    int head[N],esum;
    inline void add(int fr,int to,int val){
    	e[++esum]=(edge){to,val,head[fr]};head[fr]=esum;
    }
    
    int dis[N];
    bool vis[N];
    struct node{
    	int pl,dis;
    };
    inline bool operator <(node s1,node s2){
    	return s2.dis<s1.dis;
    }
    priority_queue<node>q;
    
    signed main(){
    	
    	#ifdef feyn
    	freopen("in.txt","r",stdin);
    	#endif
    	
    	read(m);
    	for(int i=1;i<=m;i++){
    		read(num[i]);lc=lcm(lc,num[i]);
    		for(int j=0;j<num[i];j++)read(a[i][j]);
    	}
    	num[0]=num[m+1]=1;
    	//0 to 1
    	//S to 0
    	//m+1 to T
    	for(int i=0;i<lc;i++){
    		add(0,p(i,0),0);
    		add(p(i,(m+1)),1,0);
    		int nt=(i+1)%lc;
    		add(p(i,0),p(nt,1),a[1][nt%num[1]]);
    	}
    	for(int i=1;i<=m;i++){
    		for(int t=0;t<lc;t++){
    			int nt=(t+1)%lc;
    			add(p(t,i),p(nt,i),a[i][nt%num[i]]);
    			add(p(t,i),p(nt,i+1),a[i+1][nt%num[i+1]]);
    			add(p(t,i),p(nt,i-1),a[i-1][nt%num[i-1]]);
    		}
    	}
    	
    	memset(dis,0x3f,sizeof(dis));
    	dis[0]=0;q.push((node){0,0});
    	while(!q.empty()){
    		node now=q.top();q.pop();
    		int wh=now.pl,nd=now.dis;
    		if(vis[wh])continue;vis[wh]=true;
    		for(int i=head[wh],th;i;i=e[i].next){
    			int nval=dis[wh]+e[i].v;th=e[i].t;
    			if(nval<dis[th]){
    				dis[th]=nval;q.push((node){th,dis[th]});
    			}
    		}
    	}
    	
    	printf("%d",dis[1]);
    	
    	return 0;
    }
    
    • 1

    信息

    ID
    1336
    时间
    1000ms
    内存
    128MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者