1 条题解

  • 1
    @ 2026-6-23 18:00:39

    略水的题

    本题提及的所有最短路本人均用dijkstra,还不会的出门左转

    思路

    这道题和2026紫堡杯T3很像,都用的是同一个思路。

    题目在输入的时候就用的是“如果Ui==0U_i==0,则表示该传送器的一端连接城镇 ViV_i​,另一端尚未确定。"这是不是就提示我们建立一个临时的点00,把未知的边当作已知的边,每一次询问就是在00ii之间建立一个边权00的边。

    但是这样子每一次询问都暴力会TLE,我们还得优化。仔细思考一下,从11点到nn点会分两种情况,经过00点和不经过00点。对于第一种情况,在询问前预处理最短路即可。对于第二种情况,可以先从11号点到00号点,再从ii号点到nn号点,或者是从11号点到ii号点,再从00号点到nn号点(边都是双向的),最后给三种情况选min即可。

    AC代码

    #include<bits/stdc++.h>
    #define PII pair<int,int>
    using namespace std;
    const int N=3e5+10;
    vector<int>G[N];
    int d1[N],d2[N];
    int n,m;
    void dij(int d[],int st)
    {
    	priority_queue<PII,vector<PII>,greater<PII> >Q;
    	Q.push({0,st});d[st]=0;
    	while(!Q.empty())
    	{
    		int x=Q.top().second;Q.pop();
    		for(int i:G[x])
    		{
    			_sleep(1);
    			if(d[i]>d[x]+1)
    			{
    				d[i]=d[x]+1;
    				Q.push({d[i],i});
    			}
    		}
    	}
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1,x,y;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		G[x].push_back(y);
    		G[y].push_back(x);
    	}
    	memset(d1,0x3f,sizeof(d1));memset(d2,0x3f,sizeof(d2));
    	dij(d1,1);dij(d2,n);
    	for(int i=1;i<=n;i++)
    	{
    		int ans=min({d1[n],d1[0]+d2[i],d1[i]+d2[0]});
    		if(ans==1061109567)printf("-1 ");
    		else printf("%d ",ans);
    	}
    	return 0;
    }
    
    
    • 1

    信息

    ID
    10039
    时间
    2000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    6
    已通过
    2
    上传者