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

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

    首先还是我很sb。。。。想到了分层图想不到怎么串起来,,,以为用拓扑序搞转移,,后来感到不行。。。

    QAQ

    这种数据那么小,有明确的依赖性为嘛我想不到状压。。。(准确的说是没想到状压和分层图一起做。。。。

    还有一个。。。。。。。为什么递推不行。。。(还是我写挫了。。。老wa。。)非得记忆化。。。。。。

    (其实记忆化的话能省点不必要的状态吧。。。

    。。。。

    还有。。。和zyf一样,被卡在了。。!(s&(1<<(v-1)))。。。。。不去掉就tle。。也是喜闻乐见。。。

    QAQ

    (然后我spfa的vis标记打错了。。。。。。。调了好久。。QAQ

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    typedef long long ll;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << (#x) << " = " << (x) << endl
    #define error(x) (!(x)?puts("error"):0)
    #define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
    #define grdm(g, x, i) for(int i=g.ihead[x]; i; i=g.e[i].next)
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    
    const int N=50005, oo=0x3f3f3f3f;
    int d[22][N], vis[N], q[N], ihead[N], cnt, n, m, k;
    struct dat { int next, to, w; }e[N*10*2];
    void add1(int u, int v, int w) { e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; e[cnt].w=w; }
    void add(int u, int v, int w) { add1(u, v, w); add1(v, u, w); }
    void spfa(int s, int *f) {
    	memset(vis, 0, sizeof(int)*(n));
    	memset(f, 0x3f, sizeof(int)*(n));
    	int front=0, tail=0;
    	f[s]=0; q[tail++]=s; vis[s]=1;
    	while(front!=tail) {
    		int u=q[front++], v; if(front==N) front=0; vis[u]=0;
    		rdm(u, i) if(f[v=e[i].to]>f[u]+e[i].w) {
    			f[v]=f[u]+e[i].w;
    			if(!vis[v]) {
    				vis[v]=1;
    				if(f[q[front]]>f[v]) {
    					--front; if(front<0) front+=N;
    					q[front]=v;
    				}
    				else {
    					q[tail++]=v; if(tail==N) tail=0;
    				}
    			}
    		}
    	}
    }
    int ans[21][1<<(20)], b[22], all;
    int dfs(int u, int s) {
    	if(ans[u][s]>=0) return ans[u][s];
    	if(s==all) return d[u][n-1];
    	int &a=ans[u][s]; a=oo;
    	for1(v, 1, k) if((b[v]&s)==b[v]) a=min(a, d[u][v]+dfs(v, s|(1<<(v-1))));
    	return a;
    }
    int main() {
    	read(n); read(m); read(k);
    	for1(i, 1, m) { int u=getint(), v=getint(), w=getint(); add(u-1, v-1, w); }
    	for1(i, 0, k) spfa(i, d[i]);
    	read(m);
    	for1(i, 1, m) { int u=getint(), v=getint(); b[v-1]|=(1<<(u-2)); }
    	all=(1<<k)-1;
    	CC(ans, -1);
    	printf("%d
    ", dfs(0, 0));
    	return 0;
    }
    

      


    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),意义如上所述。以下M行,每行包含3个整数X,Y,Z,(1<=X

    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

     
  • 相关阅读:
    学习hadoop
    贵在坚持
    保护好自己的毕业论文
    博客园与CSDN的选择
    Matlab中的“prod”函数
    js实现HashMap()
    js常用正则表达式
    苹果手机使用替代onkeyup的方法
    keydown
    ArrayAndString(数组和字符串)
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4161153.html
Copyright © 2011-2022 走看看