• POJ1847 Tram 开关最短路


    /*
    *State: POJ1847    16 MS    716 KB    GNU C++    
    *题目大意:
    *        有N个点以及起点和终点,点与点有路相连。接下来的N行分别为点i的情况:
    *        第一个数字k表示与该点连通的点的个数,接下来输入k个数,表示与点i相
    *        连的点的编号,第一个所连的点为可以不用改扳手而直接通过,其余的点通
    *        过的话要改一次扳手,求从起点到终点改扳手的最小次数。
    *解题思路:
    *        原来以为改开关之后,还有后继性,贡献了2个wa,之后分析发现没有环,所以
    *        一个点只走一次,开关没有后继性,所以直接建图即可。
    */
    View Code
    #include <queue>
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;
    
    const int MAXN = 105;
    const int MAXE = 1000005;
    const int inf = 0x3f3f3f3f;
    
    typedef struct _node
    {
        int v, next, is;
    }N;
    N edge[2 * MAXE];
    int cntEdge, head[MAXN];
    
    typedef struct _no
    {
        int v;
        int dis;
        _no(): dis(inf) {}
        _no(int a, int b) : v(a), dis(b) {}
        friend bool operator < (const struct _no &n1, const struct _no &n2)
        {
            return n1.dis > n2.dis;
        }
    }priN;
    
    void init()
    {
        cntEdge = 0;
        for(int i = 0; i < MAXN; i++)
            head[i] = -1;
    }
    
    void addEdge(int u, int v, int is)
    {
        edge[cntEdge].v = v;
        edge[cntEdge].is = is;
        edge[cntEdge].next = head[u];
        head[u] = cntEdge++;
    }
    
    int dijkstra(int s, int e, int n)//1是起点,n是终点
    {
        int vst[MAXN] = {0};
        int dis[MAXN];
        for(int i = 0; i <= n; i++)
            dis[i] = inf;
    
        priority_queue<priN> Q;
        
        Q.push(priN(s, 0));
        dis[s] = 0;
    
        while(!Q.empty())
        {
            priN pre = Q.top();
            Q.pop();
            if(pre.v == e)
                return pre.dis;
    
            for(int f = head[pre.v]; f != -1; f = edge[f].next)
            {
                int son = edge[f].v;
                int w = edge[f].is;
    
                if(dis[son] > dis[pre.v] + w)
                {
                    dis[son] = dis[pre.v] + w;
                    Q.push(priN(son, dis[son]));
                }
            }
        }
        return -1;
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
    #endif
    
        int n, s, e;
        while(scanf("%d %d %d", &n, &s, &e) == 3)
        {
            init();
            int m, v;
            for(int i = 1; i <= n; i++)
            {
                scanf("%d", &m);
                for(int j = 0; j < m; j++)
                {
                    scanf("%d", &v);
                    addEdge(i, v, (j == 0 ? 0 : 1));
                }
            }
    
            int sol = dijkstra(s, e, n);
            printf("%d\n", sol);
        }
        return 0;
    }
  • 相关阅读:
    【Lintcode】099.Reorder List
    【Lintcode】098.Sort List
    【Lintcode】096.Partition List
    【Lintcode】036.Reverse Linked List II
    C++中使用TCP传文件
    链表中倒数第k个结点
    剪贴板(进程通信)
    调整数组顺序使奇数位于偶数前面
    TCP数据流
    快速幂和同余模
  • 原文地址:https://www.cnblogs.com/cchun/p/2667591.html
Copyright © 2020-2023  润新知