Codeforces Round #605 (Div. 3) E - Nearest Opposite Parity (超级源点)

?? ?? ??
题意:一个数组,i位置可以到达i +/- a[ i ] 位置(不越界情况下),问你每个位置要走到一个奇偶性相反的地点最少要走几次,

在现场,,然而我真的不会哈哈哈哈我好菜??

主要是两点:超级源点(多源变单源)+ 反向建边(反向思维)

建立一个超级奇数点,一个超级偶数点;
超级奇数点为例,从该点出发,配合我们建立的反向边,
如果可以到达某个偶数点,求得的距离肯定是所有能到达他的奇数点中最小的(最短路中任意一条子路最短)

还有就是图里面写搜索记得开vis,,,树里面搜索可以不写,不等于父节点就好了(搜索待补充)

//n+1奇数0偶数超级源点
int n,a[MAXN];
vector<pii>edge[MAXN];
int dis[MAXN],vis[MAXN],ans[MAXN];
void spfa(int u)
{
    rep(i,n+2) dis[i]=1<<30,vis[i]=0;
    queue<int>q;q.push(u);
    dis[u]=0;vis[u]=1;
    while(q.size())
    {
        u=q.front(),q.pop();vis[u]=0;
        for(auto x:edge[u])
        {
            int v=x.first;
            if(dis[v]>x.second+dis[u])
            {
                dis[v]=x.second+dis[u];
                if(vis[v]==0) vis[v]=1,q.push(v);
            }
        }
    }
}
int main()
{
    fast;
    cin>>n;
    rpp(i,n)
    {
        cin>>a[i];
        if(i+a[i]<=n) edge[i+a[i]].push_back(make_pair(i,1));
        if(i-a[i]>=1)  edge[i-a[i]].push_back(make_pair(i,1));
    }
    rpp(i,n)
    {
        if(a[i]%2) edge[n+1].push_back(make_pair(i,0));
        else edge[0].push_back(make_pair(i,0));
        ans[i]=-1;
    }
    spfa(0);
    rpp(i,n) if(a[i]%2==1&&dis[i]!=1<<30) ans[i]=dis[i];
    spfa(n+1);
    rpp(i,n) if(a[i]%2==0&&dis[i]!=1<<30) ans[i]=dis[i];
    rpp(i,n) cout<<ans[i]<<" ";
    cout<<endl;
    //stop;
    return 0;
}

原文地址:https://www.cnblogs.com/Herlo/p/12037514.html

时间: 2024-08-28 16:37:22

Codeforces Round #605 (Div. 3) E - Nearest Opposite Parity (超级源点)的相关文章

Codeforces Round #605 (Div. 3) E - Nearest Opposite Parity

题目链接:http://codeforces.com/contest/1272/problem/E 题意:给定n,给定n个数a[i],对每个数输出d[i]. 对于每个i,可以移动到i+a[i]和i-a[i](如果i+a[i]<=n,i-a[i]>=1) d[i]是指从i移动到任意一个j的步数,需满足条件a[i]和a[j]的奇偶性不同 不论奇偶,相连的边先放进vector邻接表中 如果i和i+a[i]奇偶性不同,那么ans[i]为1,把i放到queue队列里 同理,如果i和i-a[i]奇偶性不同

Codeforces Round #605 (Div. 3)

地址:http://codeforces.com/contest/1272 A. Three Friends 仔细读题能够发现|a-b| + |a-c| + |b-c| = |R-L|*2 (其中L = min{a, b, c}, R = max{a, b, c}) 那么本题的移动条件就只考虑两个端点L, R即可,答案即为 |(L+1)-(R-1)| 即L向右移动1,R向左移动1,在此之前判断一下原L,R之间的距离是否<=2,<=2输出0 #include <bits/stdc++.h&

Codeforces Round #605(Div3)A~E

Codeforces Round #605(Div3)A~E A. Three Friends 题意: 给三个数\(a,b,c\),对每一个数字可以进行一次操作,加一减一或者不变. 求三个数两两组合的差值绝对值的最小值. 思路: 先排个序. 假设排序后三个数从小到大是\(a,b,c\). 那么他们的两两差就是\((c-b)+(c-a)+(b-a)=2c-2a\). 为了让他们的\(2c-2a\)最小,那就缩小\(c\),增大\(a\). #include<bits/stdc++.h> usin

Codeforces Round #Pi (Div. 2) (STL专场)

Codeforces Round #Pi (Div. 2) A - Lineland Mail 水题,拼手速. /* * @author Novicer * language : C++/C */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除