码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-12-14 00:04:16      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:n+2   div   contest   最短路   site   first   amp   情况   cpp   

?? ?? ??
题意:一个数组,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;
}

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

标签:n+2   div   contest   最短路   site   first   amp   情况   cpp   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!