zoukankan      html  css  js  c++  java
  • [POI 2007] 旅游景点

    [题目链接]

            https://www.lydsy.com/JudgeOnline/problem.php?id=1097

    [算法]

             首先,用Dijkstra算法求出2-k+1到每个点的最短路

             然后,我们用f[S][i]表示目前停留城市集合为S,现在在城市i,最短的路径

             状压DP即可

    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 20010
    #define MAXM 200010
    #define MAXK 25
    const int INF = 2e9;
    const int MAXS = 1 << 20;
    
    int i,j,x,n,m,k,u,v,w,tot,g,ts,ans,Mask;
    int head[MAXN],s[MAXK];
    int dist[MAXK][MAXN],f[MAXS][MAXK];
    bool visited[MAXN];
    
    struct Edge
    {
        int to,w,nxt;
    } e[MAXM << 1];
    
    inline void addedge(int u,int v,int w)
    {
        tot++;
        e[tot] = (Edge){v,w,head[u]};
        head[u] = tot;
    }
    inline void dijkstra(int s)
    {
        int i,v,w;
        priority_queue< pair<int,int> > q;
        pair<int,int> cur;
        for (i = 1; i <= n; i++) 
        {
            dist[s][i] = INF;
            visited[i] = false;
        }
        dist[s][s] = 0;
        q.push(make_pair(0,s));
        while (!q.empty())
        {
            cur = q.top();
            q.pop();
            if (visited[cur.second]) continue;
            visited[cur.second] = true;
            for (i = head[cur.second]; i; i = e[i].nxt)
            {
                v = e[i].to;
                w = e[i].w;
                if (dist[s][cur.second] + w < dist[s][v])
                {
                    dist[s][v] = dist[s][cur.second] + w;
                    q.push(make_pair(-dist[s][v],v));
                }
            }
        }
    }
    int main()
    {
        
        scanf("%d%d%d",&n,&m,&k);
        for (i = 1; i <= m; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);    
        }
        scanf("%d",&g);
        for (i = 1; i <= g; i++)    
        {
            scanf("%d%d",&u,&v);
            s[v] |= (1 << (u - 2));    
        }
        for (i = 1; i <= k + 1; i++) dijkstra(i);
        Mask = (1 << k) - 1;
        for (i = 0; i <= Mask; i++)
        {
            for (j = 1; j <= k + 1; j++)
            {
                f[i][j] = INF;
            }
        }
        for (i = 2; i <= k + 1; i++) 
        {
            if (!s[i])
                f[1 << (i - 2)][i] = dist[i][1];
        }
        f[0][1] = 0;
        for (i = 0; i <= Mask; i++)
        {
            for (j = 1; j <= k + 1; j++)
            {
                for (x = 2; x <= k + 1; x++)
                {
                    ts = i | (1 << (x - 2));
                    if (((s[x] & i) == s[x]) && f[i][j] + dist[j][x] < f[ts][x])
                        f[ts][x] = f[i][j] + dist[j][x];    
                }    
            }    
        }
        ans = INF;
        for (i = 1; i <= k + 1; i++) ans = min(ans,f[Mask][i] + dist[i][n]);
        printf("%d
    ",ans);
        
        return 0;
    }
  • 相关阅读:
    jquery堆栈与队列
    类数组转成数组对象
    python基础教程总结8——特殊方法,属性,迭代器,生成器,八皇后问题
    python基础教程总结7——异常
    python基础教程总结6——类
    python基础教程总结5——函数
    python基础教程总结4—基本语句
    python——动态类型
    python基础教程总结3—字典
    python基础教程总结2——字符串
  • 原文地址:https://www.cnblogs.com/evenbao/p/9343444.html
Copyright © 2011-2022 走看看