zoukankan      html  css  js  c++  java
  • Graph HDU

    HDU - 4725 题目链接

    题目大意

    这是一个分层的图。

    • 层与层之间的点可以互相到达,但是在同一层的点如果没有边的话,不能直接相连。
    • 有的点之间有边相连,可以直接互通不用通过楼层,当然也可以通过楼层如果更快的话。

    难点和处理方式

    m条边建立边简单,关键就是如何处理好层与层之间的点的关系。

    我们额外引入n个点充当楼层,编号n + 1 ~ n + n
    我们在楼层与当前楼层的点直接建立边,注意这里一定是方向相同的单向边

    如下图,我们假定点1,2在第一层,点3,在第二层,并且每个点之间没有边可以互相到达,每个楼层的花费是cost
    从1 -> 2只有一条路,从第一层的点1走到第二层的点3,再通过第二层的点3走到第一层的点2,花费是2cost

    假如我们对楼层和楼层上的点建立双向边,点1 -> 2的花费就是0了。
    因此我们对楼层和再这个楼层上的点之间必须建立统一的边,从楼层到点,或者从点到楼层

    //Powered by CK 2020:04:08
    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int, int> PII;
    const int INF = 0x3f3f3f3f;
    const int N = 1e6 + 10;
    int head[N], to[N], value[N], nex[N], cnt;
    int visit[N], dis[N], n, m, cost;
    struct cmp {
    	bool operator () (const PII & a, const PII & b) const {
    		return a.second > b.second;
    	}
    };
    void add(int x, int y, int w) {
    	to[cnt] = y;
    	value[cnt] = w;
    	nex[cnt] = head[x];
    	head[x] = cnt++;
    }
    int Dijkstra() {
    	memset(dis, 0x3f, sizeof dis);
    	memset(visit, 0, sizeof visit);
    	priority_queue<PII, vector<PII>, cmp> q;
    	q.push(make_pair(1, 0));
    	dis[1] = 0;
    	while(!q.empty()) {
    		int temp = q.top().first;
    		q.pop();
    		if(visit[temp])	continue;
    		visit[temp] = 1;
    		for(int i = head[temp]; i; i = nex[i]) {
    			if(dis[to[i]] > dis[temp] + value[i]) {
    				dis[to[i]] = dis[temp] + value[i];
    				q.push(make_pair(to[i], dis[to[i]]));
    			}
    		}
    	}
    	return dis[n] == INF ? -1 : dis[n];
    }
    int main() {
    	// freopen("in.txt", "r", stdin);
    	int t, x, y, w;
    	scanf("%d", &t);
    	for(int cas = 1; cas <= t; cas++) {
    		printf("Case #%d: ", cas);
    		scanf("%d %d %d", &n, &m, &cost);
    		memset(head, 0, sizeof head);
    		cnt = 1;
    		for(int i = 1; i<= n; i++) {
    			scanf("%d", &x);
    			add(i, x + n, 0);//点到楼层
    			// add(x + n, i, 0);//楼层到点————二选一
    			if(x - 1 >= 1)	add(x - 1 + n, i, cost), add(i, x - 1 + n, cost);
    			if(x + 1 <= n)	add(x + 1 + n, i, cost), add(i, x + 1 + n, cost);
    		}
    		for(int i = 0; i < m; i++) {
    			scanf("%d %d %d", &x, &y, &w);
    			add(x, y, w);
    			add(y, x, w);
    		}
    		printf("%d
    ", Dijkstra());
    	}
    	return 0;
    }
    
  • 相关阅读:
    javascript数组查重方法总结
    html5的web存储
    掌握javascript中的最基础数据结构-----数组
    ES解决geoip的location不为geo_point格式
    elk默认分片只有1000导致索引没有创建
    Polysh批量管理服务器
    Git永久删除文件和历史记录
    windows下设置JupyterNotebook默认目录
    windwos安装RabbitMQ
    win7计划任务报该任务映像己损坏或己篡改
  • 原文地址:https://www.cnblogs.com/lifehappy/p/12661859.html
Copyright © 2011-2022 走看看