zoukankan      html  css  js  c++  java
  • 加工零件(奇偶最短路)

    加工零件:https://www.luogu.com.cn/problem/P5663

    一下解释部分借鉴 fdszlzldalao

    观察发现,由于1->2的路径长度为1,只要点2的阶段为奇数,则点1一定要提供原材料(1->2->1->2->...)

    观察发现,由于1->2->3的路径长度为2,只要点3的阶段为偶数,则点1一定要提供原材料

    从1到v,路径很多,长度不尽相同。如果1到v的路径长度存在4时,v在阶段4、6、8、10…时,1肯定可以为0。当v的路径长度存在3时,v在3、5、7、9…阶段,1肯定可以为0。

    因此要求的就是1到v的最短奇数路径和最短偶数路径。

    若v的阶段为偶数x,存在v的最短偶数路径y,满足x>=y,1即可为0。

    若v的阶段为奇数x,存在v的最短奇数路径y,满足x>=y,1即可为0。

    设dis[v][0]为1到v的最短偶数路径,设dis[v][1]为1到v的最短奇数路径,

    则有:

    dis[v][0] = min(dis[v][0],dis[u][1]+1)
    dis[v][1] = min(dis[v][1],dis[u][0]+1)

    对于初始点1,dis[1][0]显然等于0,dis[1][1]显然不可能,设为无穷大。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=200009;
    int head[maxn],dis[maxn][2],n,m,cnt=1,vis[100009],s,l,r;
    struct p{
        int x,num;
        bool operator < (const p&tmp)    const{
            return x>tmp.x;
        }
    };
    priority_queue<p>q;
    struct node{
        int to,nxt,w;
    }d[maxn];
    void add(int u,int v,int w){
        d[cnt].to=v,d[cnt].w=w,
        d[cnt].nxt=head[u],head[u]=cnt++;    
    }
    void ji(int z,int k){
        p t;t.num=k,t.x=z;
        if(z%2==1&&dis[k][1]>z)
        {
            dis[k][1]=z;
            q.push(t);
        }
        if(z%2==0&&dis[k][0]>z)
        {
            dis[k][0]=z;
            q.push(t);
        }
    }
    void dij()
    {
        memset(dis,20,sizeof(dis));
        dis[1][0]=0;p init;//起始偶数为0 
        init.num=1,init.x=0;q.push(init);
        while(!q.empty())
        {
            p ans=q.top();q.pop();
            if(vis[ans.num])    continue;
            vis[ans.num]=0;
            for(int i=head[ans.num];i;i=d[i].nxt)
            {
                int z=dis[ans.num][0]+d[i].w;
                ji(z,d[i].to);
                z=dis[ans.num][1]+d[i].w;
                ji(z,d[i].to);
            }
        }
    }
    int main()
    {
        cin>>n>>m>>s;
        for(int i=1;i<=m;i++)
        {
            cin>>l>>r;
            add(l,r,1);add(r,l,1);
        }
        dij();
        for(int i=1;i<=s;i++)
        {
            cin>>l>>r;
            if(r%2==1&&dis[l][1]<=r)    cout<<"Yes";
            else if(r%2==0&&dis[l][0]<=r)    cout<<"Yes";
            else    cout<<"No";
            cout<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ABP源码分析四十:ZERO的Application和Tenant
    ABP源码分析三十九:ABP.Hangfire
    ABP源码分析三十八: ABP.Web.Api.OData
    ABP源码分析三十七:ABP.Web.Api Script Proxy API
    232. 用栈实现队列
    155. 最小栈
    725. 分隔链表
    328. 奇偶链表
    148. 排序链表
    143. 重排链表
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12460495.html
Copyright © 2011-2022 走看看