• 【NOIP 2017】宝藏 D2 T2


    参考From 传送门
    写的很清晰了
    AC code:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 12;
    const int MAXS = 4096;
    const int INF = 0x3f3f3f3f;
    int n, m, dis[MAXN][MAXN], ext[MAXS], dp[MAXS][MAXN];
    
    inline bool chkmin(int &x, int y) { return y < x ? x = y, 1 : 0; }
    
    int main ()
    {
    	int x, y, z;
    	memset(dis, 0x3f, sizeof dis);
    	scanf("%d%d", &n, &m);
    	for(int i = 0; i < m; i++)
    		scanf("%d%d%d", &x, &y, &z), dis[y-1][x-1] = dis[x-1][y-1] = min(dis[x-1][y-1], z);
    	for(int i = 0; i < n; i++) dis[i][i] = 0;
    	int all = (1<<n)-1;
    	for(int i = 0; i <= all; i++)
    		for(int j = 0; j < n; j++) if(i & (1<<j))
    			for(int k = 0; k < n; k++)
    				if(dis[j][k] != INF) ext[i] |= (1<<k);
    	memset(dp, 0x3f, sizeof dp);
    	for(int i = 0; i < n; i++) dp[1<<i][0] = 0;
    	for(int s = 1; s <= all; s++)
    		for(int s0 = (s-1)&s; s0; s0 = (s0-1)&s) if((ext[s0] | s) == ext[s0])
    		{
    			int ss = s^s0, sum = 0;
    			for(int i = 0; i < n; i++) if(ss & (1<<i))
    			{
    				int tmp = INF;
    				for(int j = 0; j < n; j++) if(s0 & (1<<j))
    					chkmin(tmp, dis[j][i]);
    				sum += tmp;	
    			}		
    			for(int i = 1; i < n; i++)
    				chkmin(dp[s][i], dp[s0][i-1] + sum * i);
    		}
    	int Ans = INF;
    	for(int i = 0; i < n; i++) chkmin(Ans, dp[all][i]);
    	printf("%d
    ", Ans);
    }
    
  • 相关阅读:
    Java Thread 源码
    新的篇章,新的开始,寄没有的希望于未来。
    命名的常用关键字
    通俗易懂的TCP三次握手
    Java多态
    servlet容器工作顺序
    IOC思想
    Spring MVC工作流程
    一对一,一对多,多对多
    JDBC的步骤
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039480.html
Copyright © 2020-2023  润新知