• POJ3268 Silver Cow Party 单向图_来去最短


    /*
    *State: POJ3268     Accepted    3324K    16MS    C++    1947B
    *题目大意:
    *        给定一个有向图(可带环),然后要求所有点到特定点e的距离,然后规定每个
    *        点到e之后,还要返回原地,注意图是有向图,去跟回来的路径可能不同。
    *解题思路:
    *        为了减少运算时间,可以建立正图跟反图,然后两遍spfa即可求解。
    *     各种最短路均可求,注意复杂度即可。
    */

    spfa+邻接表:

    View Code
    #include <iostream>
    #include <queue>
    using namespace std;
    
    const int MAXN = 1005;
    const int MAXE = 100005;
    const int inf = 0x3f3f3f3f;
    
    typedef struct _node
    {
        int v, w;
        int next;
        int op;
        _node(): op(0) {}
    }N;
    
    N edge[2 * MAXE];
    int head[MAXN], cntEdge, endDis[MAXN];
    
    void init(int n)
    {
        cntEdge = 0;
        for(int i = 0; i <= n; i++)
        {
            head[i] = -1;
        }
    }
    
    void addEdge(int u, int v, int w)
    {
        edge[cntEdge].v = v;
        edge[cntEdge].w = w;
        edge[cntEdge].op = 0;
        edge[cntEdge].next = head[u];
        head[u] = cntEdge++;
    
        edge[cntEdge].v = u;
        edge[cntEdge].w = w;
        edge[cntEdge].op = 1;
        edge[cntEdge].next = head[v];
        head[v] = cntEdge++;
    }
    
    
    int spfa(int s, int n, int dir)//dir == 1反图
    {
        int dis[MAXN], vst[MAXN] = {0};
        for(int i = 0; i <= n; i++)
            dis[i] = inf;
    
        queue<int> Q;
        Q.push(s);
        vst[s] = 1;
        dis[s] = 0;
    
        while(!Q.empty())
        {
            int pre = Q.front();
            Q.pop();
            vst[pre] = 0;
    
            for(int f = head[pre]; f != -1; f = edge[f].next)
            {
                if(dir == 0)
                {
                    if(edge[f].op == 1)
                        continue;
                }
                else
                {
                    if(edge[f].op == 0)
                        continue;
                }
    
                int son = edge[f].v, w = edge[f].w;
                if(dis[pre] + w < dis[son])
                {
                    dis[son] = dis[pre] + w;
                    if(!vst[son])
                    {
                        vst[son] = 1;
                        Q.push(son);
                    }
                }
            }
        }
    
        int Max = 0;
        if(!dir)
            for(int i = 1; i <= n; i++)
                endDis[i] = dis[i];
        else
        {
            for(int i = 1; i <= n; i++)
            {
                if(endDis[i] + dis[i] > Max)
                    Max = endDis[i] + dis[i];
            }
        }
        return Max;
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    
        int n, m, e;
        while(scanf("%d %d %d", &n, &m, &e) == 3)
        {
            init(n);
            int u, v, w;
            for(int i = 0; i < m; i++)
            {
                scanf("%d %d %d", &u, &v, &w);
                addEdge(u, v, w);
            }
            //正图
            spfa(e, n, 0);
            //反图
            int sol;
            sol = spfa(e, n, 1);
    
            printf("%d\n", sol);
        }
        return 0;
    }

    普通dijkstra+邻接表

    View Code
    //State: POJ3268    Accepted    3304K    32MS    C++    1971B
    #include <iostream>
    #include <queue>
    using namespace std;
    
    const int MAXN = 1005;
    const int MAXE = 100005;
    const int inf = 0x3f3f3f3f;
    
    typedef struct _node
    {
        int v, w;
        int next;
        int op;
        _node(): op(0) {}
    }N;
    
    N edge[2 * MAXE];
    int head[MAXN], cntEdge, endDis[MAXN];
    
    void init(int n)
    {
        cntEdge = 0;
        for(int i = 0; i <= n; i++)
        {
            head[i] = -1;
        }
    }
    
    void addEdge(int u, int v, int w)
    {
        edge[cntEdge].v = v;
        edge[cntEdge].w = w;
        edge[cntEdge].op = 0;
        edge[cntEdge].next = head[u];
        head[u] = cntEdge++;
    
        edge[cntEdge].v = u;
        edge[cntEdge].w = w;
        edge[cntEdge].op = 1;
        edge[cntEdge].next = head[v];
        head[v] = cntEdge++;
    }
    
    
    int dijkstra(int s, int n, int dir)//dir == 1反图
    {
        int dis[MAXN], vst[MAXN] = {0};
        for(int i = 0; i <= n; i++)
            dis[i] = inf;
        dis[s] = 0;
    
        for(int i = 0; i < n - 1; i++)
        {
            int Min = INT_MAX, index;
            for(int j = 1; j <= n; j++)
            {
                if(dis[j] < Min && !vst[j])
                {
                    Min = dis[j];
                    index = j;
                }
            }
            vst[index] = 1;
    
            for(int f = head[index]; f != -1; f = edge[f].next)
            {
                if(dir == 0)
                {
                    if(edge[f].op == 1)
                        continue;
                }
                else
                {
                    if(edge[f].op == 0)
                        continue;
                }
                int son = edge[f].v, w = edge[f].w;
                if(dis[index] + w < dis[son] && !vst[son])
                    dis[son] = dis[index] + w;
            }
        }
        
    
        int Max = 0;
        if(!dir)
            for(int i = 1; i <= n; i++)
                endDis[i] = dis[i];
        else
        {
            for(int i = 1; i <= n; i++)
            {
                if(endDis[i] + dis[i] > Max)
                    Max = endDis[i] + dis[i];
            }
        }
        return Max;
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    
        int n, m, e;
        while(scanf("%d %d %d", &n, &m, &e) == 3)
        {
            init(n);
            int u, v, w;
            for(int i = 0; i < m; i++)
            {
                scanf("%d %d %d", &u, &v, &w);
                addEdge(u, v, w);
            }
            //正图
            dijkstra(e, n, 0);
            //反图
            int sol;
            sol = dijkstra(e, n, 1);
    
            printf("%d\n", sol);
        }
        return 0;
    }

    优先队列+dijkstra+邻接表

    View Code
    //State: POJ3268    Accepted 3340K    32MS    C++    2238B
    #include <iostream>
    #include <queue>
    #include <functional>
    #include <vector>
    using namespace std;
    
    const int MAXN = 1005;
    const int MAXE = 100005;
    const int inf = 0x3f3f3f3f;
    
    typedef struct _node
    {
        int v, w;
        int next;
        int op;
        _node(): op(0) {}
    }N;
    
    typedef struct _priNode
    {
        int v, dis;
        //_priNode(): dis(inf) {}
        _priNode(int a, int b): v(a), dis(b) {}
        friend bool operator < (const _priNode &n1, const _priNode &n2)
        {
            return n1.dis > n2.dis;
        }
    }PN;
    
    N edge[2 * MAXE];
    int head[MAXN], cntEdge, endDis[MAXN];
    
    void init(int n)
    {
        cntEdge = 0;
        for(int i = 0; i <= n; i++)
        {
            head[i] = -1;
        }
    }
    
    void addEdge(int u, int v, int w)
    {
        edge[cntEdge].v = v;
        edge[cntEdge].w = w;
        edge[cntEdge].op = 0;
        edge[cntEdge].next = head[u];
        head[u] = cntEdge++;
    
        edge[cntEdge].v = u;
        edge[cntEdge].w = w;
        edge[cntEdge].op = 1;
        edge[cntEdge].next = head[v];
        head[v] = cntEdge++;
    }
    
    
    int dijkstra(int s, int n, int dir)//dir == 1反图
    {
        int dis[MAXN], vst[MAXN] = {0};
        for(int i = 0; i <= n; i++)
            dis[i] = inf;
        
        dis[s] = 0;
        priority_queue<PN> PQ;
        PN pre(s, 0);
        PQ.push(pre);
        
        while(!PQ.empty())
        {
            PN pre = PQ.top();
            PQ.pop();
            vst[pre.v] = 1;
    
            for(int f = head[pre.v]; f != -1; f = edge[f].next)
            {
                if(dir == 0)
                {
                    if(edge[f].op == 1)
                        continue;
                }
                else
                {
                    if(edge[f].op == 0)
                        continue;
                }
                int son = edge[f].v, w = edge[f].w;
    
                if(dis[pre.v] + w < dis[son] && !vst[son])
                {
                    dis[son] = dis[pre.v] + w;
                    PN pnSon(son, dis[son]);
                    PQ.push(pnSon);
                }
            }
        }
    
        int Max = 0;
        if(!dir)
            for(int i = 1; i <= n; i++)
                endDis[i] = dis[i];
        else
        {
            for(int i = 1; i <= n; i++)
            {
                if(endDis[i] + dis[i] > Max)
                    Max = endDis[i] + dis[i];
            }
        }
        return Max;
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    
        int n, m, e;
        while(scanf("%d %d %d", &n, &m, &e) == 3)
        {
            init(n);
            int u, v, w;
            for(int i = 0; i < m; i++)
            {
                scanf("%d %d %d", &u, &v, &w);
                addEdge(u, v, w);
            }
            //正图
            dijkstra(e, n, 0);
            //反图
            int sol;
            sol = dijkstra(e, n, 1);
    
            printf("%d\n", sol);
        }
        return 0;
    }

    优化+Bellman_ford+邻接表

    View Code
    #include <iostream>
    #include <queue>
    using namespace std;
    
    const int MAXN = 1005;
    const int MAXE = 100005;
    const int inf = 0x3f3f3f3f;
    
    typedef struct _node
    {
        int u, v, w;
        int next;
        int op;
        _node(): op(0) {}
    }N;
    
    N edge[2 * MAXE];
    int head[MAXN], cntEdge, endDis[MAXN];
    
    void init(int n)
    {
        cntEdge = 0;
        for(int i = 0; i <= n; i++)
        {
            head[i] = -1;
        }
    }
    
    void addEdge(int u, int v, int w)
    {
        edge[cntEdge].u = u;
        edge[cntEdge].v = v;
        edge[cntEdge].w = w;
        edge[cntEdge].op = 0;
        edge[cntEdge].next = head[u];
        head[u] = cntEdge++;
    
        edge[cntEdge].u = v;
        edge[cntEdge].v = u;
        edge[cntEdge].w = w;
        edge[cntEdge].op = 1;
        edge[cntEdge].next = head[v];
        head[v] = cntEdge++;
    }
    
    int dijkstra(int s, int n, int dir)//dir == 1反图
    {
        int dis[MAXN];
        for(int i = 0; i <= n; i++)
            dis[i] = inf;
        dis[s] = 0;
    
        for(int i = 0; i < n - 1; i++)
        {
            bool flag = false;
            for(int j = 0; j < cntEdge; j++)
            {
                if(dir == 0)
                {
                    if(edge[j].op == 1)
                        continue;
                }
                else
                {
                    if(edge[j].op == 0)
                        continue;
                }
                int u = edge[j].u, v = edge[j].v;
                int w = edge[j].w;
                if(dis[v] > dis[u] + w)
                {
                    dis[v] = dis[u] + w;
                    flag = true;
                }
            }
            if(!flag)
                break;
        }
        //判断负环就免了,此题没有
    
        int Max = 0;
        if(!dir)
            for(int i = 1; i <= n; i++)
                endDis[i] = dis[i];
        else
        {
            for(int i = 1; i <= n; i++)
            {
                if(endDis[i] + dis[i] > Max)
                    Max = endDis[i] + dis[i];
            }
        }
        return Max;
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
    #endif
    
        int n, m, e;
        while(scanf("%d %d %d", &n, &m, &e) == 3)
        {
            init(n);
            int u, v, w;
            for(int i = 0; i < m; i++)
            {
                scanf("%d %d %d", &u, &v, &w);
                addEdge(u, v, w);
            }
            //正图
            dijkstra(e, n, 0);
            //反图
            int sol;
            sol = dijkstra(e, n, 1);
    
            printf("%d\n", sol);
        }
        return 0;
    }
  • 相关阅读:
    奇葩的Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
    dubbo的本地存根
    已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数。
    数字字符串转换成与其面值相同的长整形整数
    PHP实现MySQL的主键id自动重新自增排序
    四叶玫瑰数
    PHP动态实现从数据库中访问链接到标签a的herf中
    Proteus8.0的main.asm源代码使用
    Office 2010 安装和激活出错解决办法
    PHP实现文件读写中英文数据分割插入数组代码
  • 原文地址:https://www.cnblogs.com/cchun/p/2645054.html
Copyright © 2020-2023  润新知