zoukankan      html  css  js  c++  java
  • BZOJ 1097: [POI2007]旅游景点atr( 最短路 + 状压dp )

    先最短路预处理, 然后状压就行了 

    --------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    #include<queue>
     
    using namespace std;
     

    #define b(i) (1 << (i))

    typedef pair<int, int> pii;
     
    inline int read() {
    char c = getchar();
    int ret = 0;
    for(; !isdigit(c); c = getchar());
    for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
    return ret;
    }
     
    const int maxn = 20009;
    const int maxk = 21;
    const int INF = 0X3F3F3F3F;
     
    bool vis[maxn];
    int F[maxn], _F[maxn];
    int dp[b(maxk)][maxk];
    int N, K;
     
    struct edge {
    int to, w;
    edge* next;
    } E[400009], *pt = E, *head[maxn];
     
    void AddEdge(int u, int v, int w) {
    pt->to = v; pt->w = w; pt->next = head[u]; head[u] = pt++;
    }
     
    struct DIJKSTRA {
    int d[maxn];
    priority_queue<pii, vector<pii>, greater<pii> > q;
    void Work(int s) {
    for(int i = 0; i < N; i++) d[i] = INF;
    q.push(make_pair(d[s] = 0, s));
    while(!q.empty()) {
    pii o = q.top(); q.pop();
    int w = o.first, x = o.second;
    if(d[x] != w) continue;
    for(edge* e = head[x]; e; e = e->next) if(d[e->to] > d[x] + e->w)
    q.push(make_pair(d[e->to] = d[x] + e->w, e->to));
    }
    }
    } d[maxk];
     
    int Dp(int s, int x) {
    int &ans = dp[s][x];
    if(~ans) return ans;
    ans = INF;
    if((_F[x] | s) != s) return ans;
    for(int i = 0; i < K; i++) if(x != i && (s & b(i)) && !(F[x] & b(i)))
    ans = min(Dp(s ^ b(x), i) + d[i].d[x + 1], ans);
    return ans;
    }
     
    void dfs(int x) {
    if(vis[x]) return;
    vis[x] = true;
    for(int i = 0; i < K; i++) if(F[x] & b(i)) {
    dfs(i);
    F[x] |= F[i];
    }
    }
     
    void Dfs(int x) {
    if(vis[x]) return;
    vis[x] = true;
    for(int i = 0; i < K; i++) if(_F[x] & b(i)) {
    Dfs(i);
    _F[x] |= _F[i];
    }
    }
     
    void Init() {
    N = read();
    int m = read();
    K = read();
    while(m--) {
    int u = read() - 1, v = read() - 1, w = read();
    AddEdge(u, v, w);
    AddEdge(v, u, w);
    }
    memset(F, 0, sizeof F);
    memset(_F, 0, sizeof _F);
    m = read();
    while(m--) {
    int u = read() - 2, v = read() - 2;
    F[u] |= b(v);
    _F[v] |= b(u);
    }
    for(int i = 0; i < K; i++)
    d[i].Work(i + 1);
    memset(vis, 0, sizeof vis);
    for(int i = 0; i < K; i++)
    if(!_F[i]) dfs(i);
    memset(vis, 0, sizeof vis);
    for(int i = 0; i < K; i++)
    if(!F[i]) Dfs(i);
    }
     
    int main() {
    Init();
    if(!K) {
    d[0].Work(0);
    printf("%d ", d[0].d[N - 1]);
    return 0;
    }
    memset(dp, -1, sizeof dp);
    for(int i = 0; i < K; i++) {
    dp[b(i)][i] = d[i].d[0];
    if(_F[i]) dp[b(i)][i] = INF;
    }
    int ans = INF;
    for(int i = 0; i < K; i++) if(!F[i])
    ans = min(ans, Dp(b(K) - 1, i) + d[i].d[N - 1]);
    printf("%d ", ans);
    return 0;
    }

    -------------------------------------------------------------------------- 

    1097: [POI2007]旅游景点atr

    Time Limit: 30 Sec  Memory Limit: 357 MB
    Submit: 1370  Solved: 298
    [Submit][Status][Discuss]

    Description

    FGD想从成都去上海旅游。在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情。经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个城市登山,而是希望去另外什么地方喝下午茶。幸运的是,FGD的旅程不是既定的,他可以在某些旅行方案之间进行选择。由于FGD非常讨厌乘车的颠簸,他希望在满足他的要求的情况下,旅行的距离尽量短,这样他就有足够的精力来欣赏风景或者是泡MM了^_^. 整个城市交通网络包含N个城市以及城市与城市之间的双向道路M条。城市自1至N依次编号,道路亦然。没有从某个城市直接到它自己的道路,两个城市之间最多只有一条道路直接相连,但可以有多条连接两个城市的路径。任意两条道路如果相遇,则相遇点也必然是这N个城市之一,在中途,由于修建了立交桥和下穿隧道,道路是不会相交的。每条道路都有一个固定长度。在中途,FGD想要经过K(K<=N-2)个城市。成都编号为1,上海编号为N,而FGD想要经过的N个城市编号依次为2,3,…,K+1. 举例来说,假设交通网络如下图。FGD想要经过城市2,3,4,5,并且在2停留的时候在3之前,而在4,5停留的时候在3之后。那么最短的旅行方案是1-2-4-3-4-5-8,总长度为19。注意FGD为了从城市2到城市4可以路过城市3,但不在城市3停留。这样就不违反FGD的要求了。并且由于FGD想要走最短的路径,因此这个方案正是FGD需要的。

    Input

    第一行包含3个整数N(2<=N<=20000),M(1<=M<=200000),K(0<=K<=20),意义如上所述。

    Output

    只包含一行,包含一个整数,表示最短的旅行距离。

    Sample Input

    8 15 4
    1 2 3
    1 3 4
    1 4 4
    1 6 2
    1 7 3
    2 3 6
    2 4 2
    2 5 2
    3 4 3
    3 6 3
    3 8 6
    4 5 2
    4 8 6
    5 7 4
    5 8 6
    3
    2 3
    3 4
    3 5

    Sample Output

    19

    HINT

     上面对应于题目中给出的例子。

    Source

  • 相关阅读:
    第二周作业
    第二次作业
    第一周作业
    我的2018年终总结
    css总结
    python中使用selenium错误-Firefox浏览器
    postman中 form-data、x-www-form-urlencoded、raw、binary的区别
    谷歌地图API(一)
    2014新年开题
    图书馆管理系统-需求分析
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5004566.html
Copyright © 2011-2022 走看看