zoukankan      html  css  js  c++  java
  • hzwer模拟赛 虫洞

    【题目描述】

    N个虫洞,M条单向跃迁路径。从一个虫洞沿跃迁路径到另一个虫洞需要消耗一定量的燃料和1单位时间。虫洞有白洞和黑洞之分。设一条跃迁路径两端的虫洞质量差为delta。

    1.从白洞跃迁到黑洞,消耗的燃料值减少delta,若该条路径消耗的燃料值变为负数的话,取为0。

    2.从黑洞跃迁到白洞,消耗的燃料值增加delta。

    3.路径两端均为黑洞或白洞,消耗的燃料值不变化。

    作为压轴题,自然不会是如此简单的最短路问题,所以每过1单位时间黑洞变为白洞,白洞变为黑洞。在飞行过程中,可以选择在一个虫洞停留1个单位时间,如果当前为白洞,则不消耗燃料,否则消耗s[i]的燃料。现在请你求出从虫洞1到N最少的燃料消耗,保证一定存在1到N的路线。

    【输入格式】

    第1行:2个正整数N,M

    第2行:N个整数,第i个为0表示虫洞i开始时为白洞,1表示黑洞。

    第3行:N个整数,第i个数表示虫洞i的质量w[i]。

    第4行:N个整数,第i个数表示在虫洞i停留消耗的燃料s[i]。

    第5..M+4行:每行3个整数,u,v,k,表示在没有影响的情况下,从虫洞u到虫洞v需要消耗燃料k。

    【输出格式】

    一个整数,表示最少的燃料消耗。

    【样例输入】

    4 5

    1 0 1 0

    10 10 100 10

    5 20 15 10

    1 2 30

    2 3 40

    1 3 20

    1 4 200

    3 4 200

    【样例输出】

    130

    【数据范围】

    对于30%的数据: 1<=N<=100,1<=M<=500

    对于60%的数据: 1<=N<=1000,1<=M<=5000

    对于100%的数据: 1<=N<=5000,1<=M<=30000

    其中20%的数据为1<=N<=3000的链

    1<=u,v<=N, 1<=k,w[i],s[i]<=200

    【样例说明】

    按照1->3->4的路线。

    /*
    把一个洞拆成黑白两个洞,然后建图
    注意虫洞跨越时的颜色是相对于同一时刻而言的
    */
    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define ll long long
    using namespace std;
    const int maxn = 30500;
    const ll inf = 987654321234LL;
    inline int read(){
        char ch=getchar();
        int f=1,x=0;
        while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();};
        while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();};
        return x*f;
    }
    struct edge{
        int v;
        int w;
        int nxt;
    }e[maxn*6];
    int n,m;
    int cnt,head[maxn],col[maxn],w[maxn],s[maxn];
    ll dis[maxn],ans;
    bool vis[maxn];
    void ins(int u,int v,int w){
        cnt++;
        e[cnt].v = v;
        e[cnt].w = w;
        e[cnt].nxt = head[u];
        head[u] = cnt;
    }
    void spfa(int st){
        for(int i = 1;i <= n+n;i++) dis[i] = inf;
        dis[st] = 0;
        queue<int> q;
        int now,to;
        q.push(st);
        vis[st] = true;
        while(!q.empty()){
            now = q.front();
            q.pop();
            for(int i = head[now];i;i = e[i].nxt){
                to = e[i].v;
                if(dis[to] > dis[now] + e[i].w){
                    dis[to] = dis[now] + e[i].w;
                    if(!vis[to]){
                        vis[to] = true;
                        q.push(to);
                    }
                }
            }
            vis[now] = false;
        }
        ans = min(dis[n],dis[n+n]);
        cout<<ans;
    }
    int main(){
        freopen("holes.in","r",stdin);
        freopen("holes.out","w",stdout);
        n = read();
        m = read();
        for(int i = 1;i <= n;i++) col[i] = read();
        for(int i = 1;i <= n;i++) w[i] = read(); 
        for(int i = 1;i <= n;i++) s[i] = read();
        int u,v,k,neww;
        for(int i = 1;i <= m;i++){
            u = read();
            v = read();
            k = read();
            if(col[u] == col[v]){
                neww = k;
                ins(u,v+n,neww);
                ins(u+n,v,neww);
            }else{
                neww = k + abs(w[u]-w[v]);
                ins(u+n,v+n,neww);
                neww = max(0,k - abs(w[u]-w[v]));
                ins(u,v,neww);
            }
        }
        for(int i = 1;i <= n;i++){
            ins(i,i+n,0);
            ins(i+n,i,s[i]);
        }
        if(col[1])spfa(1+n);
        else spfa(1);
        return 0;
    }
  • 相关阅读:
    微信小程序设置web-view的业务域名
    第61节:Java中的DOM和Javascript技术
    第61节:Java中的DOM和Javascript技术
    小程序获取时间格式
    小程序获取时间格式
    小程序弹出框详解
    小程序弹出框详解
    Python自定义包引入【新手必学】
    Go语言底层知识总结【新手必学】
    Python代码编写规范,你真的会吗?
  • 原文地址:https://www.cnblogs.com/hyfer/p/5920119.html
Copyright © 2011-2022 走看看