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;
    }
  • 相关阅读:
    IO 单个文件的多线程拷贝
    day30 进程 同步 异步 阻塞 非阻塞 并发 并行 创建进程 守护进程 僵尸进程与孤儿进程 互斥锁
    day31 进程间通讯,线程
    d29天 上传电影练习 UDP使用 ScketServer模块
    d28 scoket套接字 struct模块
    d27网络编程
    d24 反射,元类
    d23 多态,oop中常用的内置函数 类中常用内置函数
    d22 封装 property装饰器 接口 抽象类 鸭子类型
    d21天 继承
  • 原文地址:https://www.cnblogs.com/evenbao/p/9343444.html
Copyright © 2011-2022 走看看