zoukankan      html  css  js  c++  java
  • Vijos 1082 丛林探险

    题目链接:https://vijos.org/p/1082

    本题本来是练习SPFA的。我一看DIscuss能用裸搜。果断敲了一个前向星+DFS,居然超时了。后来发现是Next数组开小了,应该开成两倍边数的大小。

    后来我又把前向星改成邻接表,也AC了。。最后写一发SPFA。


    前向星+DFS+剪枝:(AC):

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <vector>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    #define INF 0x3f3f3f3f
    #define Maxn 5005
    #define Maxm 40005<<1
    
    struct Edge
    {
        int x;
        int y;
        int c;
        int d;
    };
    
    Edge e[Maxm];
    int first[Maxn];
    int next[Maxm];//注意不要写成next[Maxn],切记
    int used[Maxn];
    int k;
    int s,t;
    int n,m;
    int mma = INF;
    
    void dfs(int start,int total_len,int total_k)
    {
        //加两个剪支,体力值超过范围或者长度必然不是最优两种情况
        if(total_k > k || total_len > mma)
        {
            return;
        }
        if(start == t)
        {
            if(total_k<=k)
            {
                mma = mma>total_len ? total_len : mma;
            }
            return;
        }
        used[start] = 1;
        for(int i=first[start]; i!=-1; i=next[i])
        {
            if(used[e[i].y] == 0)
            {
                dfs(e[i].y,total_len + e[i].d ,total_k + e[i].c);
            }
        }
        used[start] = 0;
    }
    int main()
    {
    /*#ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif*/
        scanf(" %d %d",&n,&m);
        memset(first,-1,sizeof(first));
        memset(next,-1,sizeof(next));
        memset(used,0,sizeof(used));
    
        int temp = m;
        int i = 0;
        while(temp--)
        {
            scanf(" %d %d %d %d",&e[i].x,&e[i].y,&e[i].c,&e[i].d);
            next[i] = first[e[i].x];
            first[e[i].x] = i;
            i++;
            e[i].x = e[i-1].y,e[i].y = e[i-1].x,e[i].c = e[i-1].c,e[i].d = e[i-1].d;
            next[i] = first[e[i].x];
            first[e[i].x] = i;
            i++;
        }
        scanf(" %d %d %d",&s,&t,&k);
        dfs(s,0,0);
        if(mma == INF) printf("-1\n");
        else printf("%d\n",mma);
    }

    邻接表+DFS+剪枝(AC):

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <vector>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    #define INF 0xffffff
    #define Maxn 5005
    #define Maxm 40005<<1
    
    struct vertex
    {
        int n;
        int length;
        int cost;
    };
    
    vector < vertex > graph[Maxn];
    int used[Maxn];
    int k;
    int s,t;
    int n,m;
    int mma = INF;
    
    void dfs(int start,int total_len,int total_k)
    {
        //加两个剪支,体力值超过范围或者长度必然不是最优两种情况
        if(total_k <=k && total_len < mma)
        {
            if(start == t)
            {
                mma = total_len;
            }
            else
            {
                used[start] = 1;
                for(int i=0; i<graph[start].size(); i++)
                {
                    if(used[graph[start][i].n] == 0)
                    {
                        dfs(graph[start][i].n,total_len + graph[start][i].length,total_k + graph[start][i].cost);
                    }
                }
                used[start] = 0;
            }
        }
    }
    int main()
    {
        /*#ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
        #endif*/
        int st,vd,ct,le;
        scanf(" %d %d",&n,&m);
        memset(used,0,sizeof(used));
        int temp = m;
        int i = 0;
        while(temp--)
        {
            scanf(" %d %d %d %d",&st,&vd,&ct,&le);
            vertex one;
            one.n = vd;
            one.length = le;
            one.cost = ct;
            graph[st].push_back(one);
    
            vertex other;
            other.n = st;
            other.cost = ct;
            other.length = le;
            graph[vd].push_back(other);
        }
        scanf(" %d %d %d",&s,&t,&k);
        dfs(s,0,0);
        if(mma == INF) printf("-1\n");
        else printf("%d\n",mma);
    }


    前向星+SPFA (AC):

    声明两个Dist数组,一个代表时间(距离),一个代表体力值,只有两个Dist同时满足条件时,才会更新,也才有机会入队列。

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <vector>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    #define INF 0x3f3f3f3f
    #define Maxn 5005
    #define Maxm 40005<<1
    
    struct Edge
    {
        int x;
        int y;
        int c;
        int d;
    };
    
    Edge e[Maxm];
    int first[Maxn];
    int next[Maxm];
    int used[Maxn];
    int distC[Maxn];//体力
    int distD[Maxn];//时间
    
    int k;
    int s,t;
    int n,m;
    
    void spfa(int s)
    {
        queue<int> q;
        memset(used,0,sizeof(used));
        used[s] = 1;
        q.push(s);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            used[u] = 0;
            for(int i=first[u]; i!=-1; i=next[i])
            {
                int v = e[i].y;
                int c = e[i].c;
                int d = e[i].d;
                if(distD[v] - d > distD[u] && distC[u] + c <=k)
                {
                    distD[v] = distD[u] + d;
                    distC[v] = distC[u] + c;
                    if(used[v] == 0)
                    {
                        used[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
    }
    int main()
    {
        /*#ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
        #endif*/
    
        scanf(" %d %d",&n,&m);
    
        memset(first,-1,sizeof(first));
        memset(next,-1,sizeof(next));
        memset(used,0,sizeof(used));
        memset(distC,0x3f,sizeof(distC));
        memset(distD,0x3f,sizeof(distD));
    
        int temp = m;
        int i = 0;
        while(temp--)
        {
            scanf(" %d %d %d %d",&e[i].x,&e[i].y,&e[i].c,&e[i].d);
            next[i] = first[e[i].x];
            first[e[i].x] = i;
            i++;
            e[i].x = e[i-1].y,e[i].y = e[i-1].x,e[i].c = e[i-1].c,e[i].d = e[i-1].d;
            next[i] = first[e[i].x];
            first[e[i].x] = i;
            i++;
        }
        scanf(" %d %d %d",&s,&t,&k);
        distD[s] = distC[s] = 0;
        spfa(s);
        if(distD[t] == INF) printf("-1\n");
        else printf("%d\n",distD[t]);
    }
    


  • 相关阅读:
    python-Python调用wcf接口
    一个数据驱动的ui自动化框架思路
    selenium分布式部署
    UI自动化-Element is not clickable at point-----问题记录
    idea下载git代码
    windows的hosts文件路径
    端口号
    Hadoop压缩
    MongoDB(单节点)环境配置
    快排
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3000691.html
Copyright © 2011-2022 走看看