2 条题解

  • 11
    @ 2024-6-4 21:07:21
    #include<bits/stdc++.h>
    using namespace std;
    #define N 2500005
    #define inf 0x3f3f3f3f
    long long n,k;
    struct Point{//存储输入点的信息 
    	long long x,y,id;
    }a[505];
    struct Edge{//链式前向星存图 
    	long long v,w,next;
    }tu[N];
    struct Ans{//这里把dis写成结构体,方便排序 
    	long long id,w;
    }dis[505];
    long long head[N],ce,vis[505],vist[505];//vis存储一个点是否走过的信息,vist存储一个点有没有遍历过的信息,vis用于SPFA找最短路,vist用于找端点 
    inline void adde(long long u,long long v,long long w){//链式前向星添加边 
    	tu[++ce].v=v;tu[ce].w=w;tu[ce].next=head[u];
    	head[u]=ce;
    }
    inline bool cmp(Ans x,Ans b){//自定义sort排序 
    	return x.w>b.w;
    }
    long long ans=-1;//把最长上升点列的长初始化为1 
    inline void SPFA(long long x){//SPFA找最短路 
    	for(long long i=1;i<=n;i++){//每次找最短路的时候都要初始化dis和vis的值 
    		dis[i].w=inf,dis[i].id=i;
    		vis[i]=0;
    	}
    	queue<long long> q;//队列 
    	dis[x].w=0;
    	q.push(x);
    	vis[x]=1;
    	vist[x]=1;//初始化 
    	while(!q.empty()){
    		long long u=q.front();//每次获取队首元素 
    		q.pop();//将队首元素弹出 
    		vis[u]=0;
    		for(long long i=head[u];i;i=tu[i].next){//遍历每一条相连的边 
    			long long v=tu[i].v,w=tu[i].w;
    			if(dis[v].w>dis[u].w+w){//三角形不等式更新最小值 
    				dis[v].w=dis[u].w+w;
    				if(!vis[v]){//判断这个点有没有走过 
    					q.push(v);//没有的话,更新为走过,并加入队列 
    					vis[v]=1;
    				}
    			}
    		}
    	}
    	for(int i=1;i<=n;i++){
    		if(dis[i].w!=inf&&i!=x&&k>=dis[i].w){//判断添加上k个点后,端点能到哪些点 
    			vist[i]=1;//把这些点标记为非端点 
    		}
    	}
    	sort(dis+1,dis+n+1,cmp);//排序
    	for(long long i=1;i<=n;i++){
    		if(k>=dis[i].w) ans=max(ans,a[dis[i].id].x-a[x].x+a[dis[i].id].y-a[x].y+1+k-dis[i].w);//如果加上k个点后能到达这个点,更新上升点列的最大值 
    	}
    }
    int main(){
        ios::sync_with_stdio(0);//cin,cout提速 
    	cin>>n>>k;
    	for(long long i=1;i<=n;i++){
    		cin>>a[i].x>>a[i].y;
    		a[i].id=i;	
    	}
    	for(long long i=1;i<=n;i++) 
    		for(long long j=1;j<=n;j++){
    			if(a[j].x>=a[i].x&&a[j].y>=a[i].y&&i!=j){//判断如果有两个点满足非严格递增,且不是这个点本身 
    				adde(i,j,a[j].x-a[i].x+a[j].y-a[i].y-1);//加边 
    			}
    		}
        for(long long i=1;i<=n;i++){
            if(!vist[i]){//不加这一行的话会有两个点超时 
                SPFA(i);
    		}
        }
    	cout<<ans<<"\n";//输出 
    	return 0;
    }
    
    • -12
      @ 2024-4-18 17:28:55

      asasssda

      • 1

      [CSP-J 2022] 上升点列(point)

      信息

      ID
      2038
      时间
      1000ms
      内存
      256MiB
      难度
      4
      标签
      递交数
      129
      已通过
      63
      上传者