• Nearest Opposite Parity最短路径+超级源点


    time limit per test2 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output

    You are given an array a consisting of n integers. In one move, you can jump from the position i to the position i−ai (if 1≤i−ai) or to the position i+ai (if i+ai≤n).

    For each position i from 1 to n you want to know the minimum the number of moves required to reach any position j such that aj has the opposite parity from ai (i.e. if ai is odd then aj has to be even and vice versa).
    在这里插入图片描述
    input

    10
    4 5 7 6 7 5 4 4 6 4
    

    output

    1 1 1 2 -1 1 1 3 1 1 
    

    /// spfa最最短路,建立两个超级源点,一个连接奇数点一个链接偶数点,在建边的时候,边权设置为 1

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e6 + 7;
    typedef int itn;
    int n;
    int a[maxn];
    struct Node{
    	int u;
    	int v;
    	int next;
    	int w;
    }edge[maxn]; 
    int cnt;
    int head[maxn];
    int dis[maxn];
    itn ans[maxn];
    itn vis[maxn];
    void _Init(){
    	cnt = 0;
    	for(int i=0;i<maxn;i++) head[i] = -1;
    }
    void _Add(int u,int v){
    	edge[cnt].u = u;
    	edge[cnt].v = v;
    	edge[cnt].w = 1;
    	edge[cnt].next = head[u];
    	head[u] = cnt ++;
    }
    void _SPFA(int u){
    	for(int i=1;i<maxn;i++){
    		dis[i] = 0x3f3f3f3f;
    		vis[i] = 0;
    	}
    	dis[u] = 0;
    	vis[u] = 1;
    	queue<int> que;
    	///cout << que.size() <<endl;
    	que.push(u);
    	while(que.size()){
    		int t = que.front();
    		que.pop();
    		vis[t] = 0;
    		for(int i = head[t]; ~i;i = edge[i].next){
    			int to = edge[i].v;
    			if(dis[to] > dis[t] + edge[i].w){
    				dis[to] = dis[t] + edge[i].w;
    				if(vis[to] == 0){
    					que.push(to);
    					vis[to] = 1;
    				} 
    			}
    			///puts("ok");
    		}
    	} 
    }
    int main(){
    	cin >> n;
    	_Init();
    	for(int i=1;i<=n;i++) cin >> a[i];
    	for(int i=1;i<=n;i++){
    		if(i - a[i] >= 1) _Add(i - a[i],i);
    		if(i + a[i] <= n) _Add(i + a[i],i);
    		if(a[i] % 2 == 0) _Add(n+1,i);
    		else _Add(n+2,i);
    	}
    	
    	_SPFA(n + 1);
    	///puts("okay");
    	for(int i=1;i<=n;i++){
    		if(a[i] % 2) ans[i] = dis[i];
    	}
    	_SPFA(n + 2);
    	for(int i=1;i<=n;i++){
    		if(a[i] % 2 == 0) ans[i] = dis[i];
    	}
    	for(int i=1;i<=n;i++){
    		if(ans[i] == 0x3f3f3f3f) printf("-1 ");
    		else printf("%d ",ans[i] - 1);
    	}
    	///cout << 0x3f3f3f3f <<endl;
    	return 0;
    } 
    
  • 相关阅读:
    一年三百六十日,需求业务严相逼
    新博客测试
    教务流水账
    暗流涌动的话“用户体验”
    文档那些事儿
    jforum(2)中文乱码的解决方式
    jmeter笔记(4)测试上传附件
    jmeter笔记(2)组件介绍
    jmeter笔记(5)参数化CSV Data Set Config
    jmeter笔记(6)参数化函数助手
  • 原文地址:https://www.cnblogs.com/PushyTao/p/14507419.html
Copyright © 2020-2023  润新知