zoukankan      html  css  js  c++  java
  • JZOJ 5818

    Description

    一天,Y 君在测量体重的时候惊讶的发现,由于常年坐在电脑前认真学习,她的体重有了突 飞猛进的增长。

    幸好 Y 君现在退役了,她有大量的时间来做运动,她决定每天从教学楼跑到食堂来减肥。

    Y 君将学校中的所有地点编号为 1 到 n,其中她的教学楼被编号为 S,她的食堂被编号为 T, 学校中有 m 条连接两个点的双向道路,保证从任意一个点可以通过道路到达学校中的所有点。

    然而 Y 君不得不面临一个严峻的问题,就是天气十分炎热,如果 Y 君太热了,她就会中暑。 于是 Y 君调查了学校中每条路的温度 t,及通过一条路所需的时间 c。Y 君在温度为 t 的地 方跑单位时间,就会使她的热量增加 t。

    由于热量过高 Y 君就会中暑,而且 Y 君也希望在温度较低的路上跑,她希望在经过的所有 道路中最高温度最低的前提下,使她到达食堂时的热量最低 (从教学楼出发时,Y 君的热量为 0)。

    请你帮助 Y 君设计从教学楼到食堂的路线,以满足她的要求。你只需输出你设计的路线中所 有道路的最高温度和 Y 君到达食堂时的热量。

    Input

    第一行由一个空格隔开的两个正整数 n, m,代表学校中的地点数和道路数。

    接下来 m 行,每行由一个空格隔开的四个整数 a, b, t, c 分别代表双向道路的两个端点,温度 和通过所需时间.

    最后一行由一个空格隔开的两个正整数 S, T,代表教学楼和食堂的编号。

    注意:输入数据量巨大,请使用快速的读入方式。

    Output

    一行由一个空格隔开的两个整数,分别代表最高温度和热量。

    Sample Input

    5 6
    1 2 1 2
    2 3 2 2
    3 4 3 4
    4 5 3 5
    1 3 4 1
    3 5 3 6
    1 5

    Sample Output

    3 24

    Data Constraint

    10% 的数据满足 t = 0

    另外 10% 的数据满足 c = 0

    另外 30% 的数据满足 n ≤ 2000

    100% 的数据满足 n ≤ 5 × 10^5 , m ≤ 10^6 , 0 ≤ t ≤ 10000, 0 ≤ c ≤ 10^8 , 1 ≤ a, b, S, T ≤ n, S ≠ T


    看数据范围和时限觉得能行就写二分了= =

    还是太年轻

    用并查集维护连通性,将边权按从小到大排序,依次加入图中

    这样保证了 s 和 t 第一次联通时路径上的最大边权最小

    然后就可以跑最短路了

    同时还要注意的是本题计算最短路的方式与统计边权不等

    所以在 s 和 t 联通后,还要把剩下的所有与最后一条加入的边边权相等的边都加进来

    (其实就是从小到大枚举边权加入图中...

    目测不开 long long 会GG


    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cctype>
    #include<queue>
    using namespace std;
    
    typedef long long ll;
    const int MAXN = 500005, MAXM = 1000005;
    
    struct EDGE{
    	int from, nxt, to;
    	ll h, t;
    	EDGE(int FROM = 0, int NXT = 0, int TO = 0, ll H = 0ll, ll T = 0ll) {from = FROM; nxt = NXT; to = TO; h = H; t = T;}
    	bool operator < (const EDGE& b) const {
    		return h < b.h;
    	}
    }edge[MAXM << 1];
    int n, m, totedge, bgn, fnl;
    int fa[MAXN], head[MAXN];
    bool vis[MAXN];
    ll dst[MAXN];
    priority_queue<pair<ll, int> > q;
    
    inline int rd() {
    	register int x = 0;
    	register char c = getchar();
    	while(!isdigit(c)) c = getchar();
    	while(isdigit(c)) {
    		x = x * 10 + (c ^ 48);
    		c = getchar();
    	}
    	return x;
    }
    inline void add(int Num) {
    	edge[Num].nxt = head[edge[Num].from];
    	head[edge[Num].from] = Num;
    	edge[++totedge] = EDGE(edge[Num].to, head[edge[Num].to], edge[Num].from, edge[Num].h, edge[Num].t);
    	head[edge[Num].to] = totedge;
    	return;
    }
    int findfa(int x) {
    	return (x == fa[x] ? x : findfa(fa[x]));
    }
    inline bool link(int Num) {
    	int fx = findfa(edge[Num].from), fy = findfa(edge[Num].to);
    	add(Num);
    	if(fx == fy) return false;
    	fa[fx] = fy;
    	return true;
    }
    inline bool stick(int x, int y) {
    	int fx = findfa(x), fy = findfa(y);
    	return (fx == fy);
    }
    inline void dij() {
    	for(int i = 1; i <= n; ++i) dst[i] = 200000000000000ll;
    	dst[bgn] = 0;
    	q.push(make_pair(0, bgn));
    	while(!q.empty()) {
    		int x = q.top().second; q.pop();
    		if(vis[x]) continue;
    		vis[x] = true;
    		for(int i = head[x]; i; i = edge[i].nxt) {
    			int y = edge[i].to;
    			if(dst[y] > dst[x] + edge[i].h * edge[i].t) {
    				dst[y] = dst[x] + edge[i].h * edge[i].t;
    				q.push(make_pair(-dst[y], y));
    			}
    		}
    	}
    	return;
    }
    
    int main() {
    	freopen("running.in", "r", stdin);
    	freopen("running.out", "w", stdout);
    	n = rd(); m = totedge = rd();
    	for(int i = 1; i <= n; ++i) fa[i] = i;
    	for(int i = 1; i <= m; ++i) {
    		edge[i].from = rd();
    		edge[i].to = rd();
    		edge[i].h = (ll)rd();
    		edge[i].t = (ll)rd();
    	}
    	bgn = rd(); fnl = rd();
    	sort(edge + 1, edge + m + 1);
    	for(int i = 1; i <= m; ++i) {
    		link(i);
    		if(stick(bgn, fnl)) {
    			printf("%lld ", edge[i].h);
    			++i;
    			while(edge[i - 1].h == edge[i].h && i <= m) {
    				link(i); ++i;
    			}
    			break;
    		}
    	}
    	dij();
    	printf("%lld
    ", dst[fnl]);
    	return 0;
    }
    

      

    禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载 ,用户转载请注明出处:https://www.cnblogs.com/xcysblog/
  • 相关阅读:
    与众不同 windows phone (50)
    与众不同 windows phone (49)
    重新想象 Windows 8.1 Store Apps (93)
    重新想象 Windows 8.1 Store Apps 系列文章索引
    重新想象 Windows 8.1 Store Apps (92)
    重新想象 Windows 8.1 Store Apps (91)
    重新想象 Windows 8.1 Store Apps (90)
    重新想象 Windows 8.1 Store Apps (89)
    重新想象 Windows 8.1 Store Apps (88)
    重新想象 Windows 8.1 Store Apps (87)
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9484001.html
Copyright © 2011-2022 走看看