zoukankan      html  css  js  c++  java
  • [洛谷P4962]朋也与光玉

    题目大意:有一张$n(nleqslant100)$个点$m(mleqslant n(n-1)$条边的有向图,每个点有一个颜色,需要找到一条长度为$k(kleqslant13)$,恰好经过全部$k$种颜色的路径。求最短路径

    题解:状压$DP$,令$f_{i,S}$表示现在在第$i$个点,颜色状态为$S$的最短路径,要求长度也为$k$,只需要在转移的时候判断一下即可

    卡点:

    C++ Code:

    #include <cstdio>
    #define maxn 111
    #define maxm (maxn * maxn)
    #define N (1 << 13)
    const int inf = 0x3f3f3f3f;
    inline void getmin(int &a, int b) { if (a > b) a = b; };
    
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt, w;
    } e[maxm];
    inline void addedge(int a, int b, int c) {
    	e[++cnt] = (Edge) { b, head[a], c }; head[a] = cnt;
    }
    
    int n, m, k, ans = inf;
    int s[maxn], f[maxn][N];
    int main() {
    	scanf("%d%d%d", &n, &m, &k);
    	__builtin_memset(f, 0x3f, sizeof f);
    	for (int i = 1; i <= n; ++i) {
    		scanf("%d", s + i);
    		f[i][1 << s[i]] = 0;
    	}
    	for (int i = 0, a, b, c; i < m; ++i) {
    		scanf("%d%d%d", &a, &b, &c);
    		addedge(a, b, c);
    	}
    	const int U = 1 << k, I = U - 1;
    	for (int j = 1; j < U; ++j) {
    		for (int u = 1; u <= n; ++u) if (f[u][j] != inf) {
    			for (int i = head[u]; i; i = e[i].nxt) {
    				int v = e[i].to;
    				if (j >> s[v] & 1) continue;
    				getmin(f[v][j | 1 << s[v]], f[u][j] + e[i].w);
    			}
    		}
    	}
    	for (int i = 1; i <= n; ++i) getmin(ans, f[i][I]);
    	if (ans != inf) printf("%d
    ", ans);
    	else puts("Ushio!");
    	return 0;
    }
    

      

  • 相关阅读:
    javascript中replace()
    防止IE6出现BUG的十种常见解决方法
    IE6 重复字符的bug
    IE6 BUG大全
    display:inline
    JavaScript 图片上传预览效果
    用一行代码让w3wp进程崩溃,如何查找w3wp进程崩溃的原因
    近期学习任务
    气死我的存储过程和用户定义函数
    Damn,China Mobile!!!!
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10333371.html
Copyright © 2011-2022 走看看