• 2020牛客国庆集训派对day2 CHEAP DELIVERIES


    https://ac.nowcoder.com/acm/contest/7818/B

    很玄乎的一个状压dp

    总的来说就是n个1的状态转换成n+1个1的状态,写法很奇妙,具体看代码吧。。。

    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<bitset>
    #include<queue>
    #include<set>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5 + 11;
    ll map[50][50];
    int n, m, k;
    ll INF = 1e17;
    
    set<int>sss;
    
    struct Node {
    	int p;
    	ll len;
    	Node(int a,ll b):p(a),len(b){}
    };
    vector<Node>G[maxn];
    
    void add(int x, int y, ll len) {
    	G[x].push_back(Node(y, len));
    }
    bitset<200>ins[100], ans[100];
    int par[maxn];
    int find(int x) {
    	if (par[x] == -1) return x;
    	return par[x] = find(par[x]);
    }
    bool operator<(Node a, Node b) {
    	return a.len > b.len;
    }
    ll dis[maxn];
    int vis[maxn];
    int dij(int s) {
    	for (int i = 0; i <= n+110 ; i++) {
    		dis[i] = INF;
    		vis[i] = 0;
    	}
    	priority_queue<Node>que;
    	dis[s] = 0;
    	que.push(Node(s, 0));
    
    	while (que.size()) {
    		Node ans = que.top();
    		que.pop();
    		if (vis[ans.p]) continue;
    		vis[ans.p] = 1;
    		for (int i = 0; i < G[ans.p].size(); i++) {
    			int p = G[ans.p][i].p;
    			if (dis[p] > dis[ans.p] + G[ans.p][i].len) {
    				dis[p] = dis[ans.p] + G[ans.p][i].len;
    				que.push(Node(p, dis[p]));
    			}
    		}
    	}
    	return 0;
    }
    int id[maxn];
    struct node {
    	int x, y;
    }que[100];
    
    ll dp[maxn][30];
    
    
    
    int main() {
    	scanf("%d%d%d", &n, &m, &k);
    	memset(par, -1, sizeof(par));
    
    	for (int i = 0; i < m; i++) {
    		int x, y;
    		ll len;
    		scanf("%d%d%lld", &x, &y, &len);
    		int a = find(x);
    		int b = find(y);
    		if (a != b) par[a] = b;
    		add(x, y, len);
    		add(y, x, len);
    	}
    	int cnt = 0;
    	for (int i = 0; i < k; i++) {
    		int x, y;
    		scanf("%d %d", &que[i].x, &que[i].y);
    		sss.insert(find(que[i].x));
    		sss.insert(find(que[i].y));
    	}
    	if (sss.size() > 1) {
    		cout << -1 << endl;
    		return 0;
    	}
    	for (int i = 0; i < k; i++) {
    		for (int j = 0; j < k; j++) {
    			map[i][j] = INF;
    		}
    	}
    	for (int i = 0; i < k; i++) {
    		dij(que[i].x);
    		for (int j = 0; j < k; j++) {
    			map[i][j] = dis[que[j].y];
    		}
    	}
    	for (int i = 0; i < maxn; i++) {
    		for (int j = 0; j < 30; j++) {
    			dp[i][j] = INF;
    		}
    	}
    	for (int i = 0; i < k; i++) dp[1 << i][i] = map[i][i];
    
    
    	ll ans = INF;
        
    	for (int i = 1; i < (1 << k); i++) {
    		for (int j = 0; j < k; j++) {
    			if (!(i &(1 << j))) continue;//i要包括状态j才行
    
    			for (int s = 0; s < k; s++) {
    				if ((i&(1 << s))) continue;
    				dp[i | (1 << s)][s] = min(dp[i | (1 << s)][s], dp[i][j] + map[j][s] + map[s][s]);
    			}
    		}
    	}
    	
    	
    	int len = (1 << k) - 1;
    	for (int i = 0; i < k; i++) {
    		ans = min(ans, dp[len][i]);
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

      

    寻找真正的热爱
  • 相关阅读:
    由DBCursor的“can't switch cursor access methods”异常引发的思考
    在Java中使用元组类型的利器
    Linux命令行如何返回上一次的目录
    Linux下通过crontab命令来实现定时任务
    Spark任务踩到的坑
    Hadoop HDFS命令学习笔记
    Spark RDD学习笔记
    HBase的基本操作
    一张图5分钟熟悉MarkDown的基本语法
    C#跨线程操作控件的最简单实现探究
  • 原文地址:https://www.cnblogs.com/lesning/p/13762452.html
Copyright © 2020-2023  润新知