zoukankan      html  css  js  c++  java
  • 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;
    } 
    
  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/PushyTao/p/14507419.html
Copyright © 2011-2022 走看看