theOldChun

ZJZSZX

[Solution] JZOJ-5818 做运动

[Solution] JZOJ-5818 做运动

Time Limits:2000ms Memory Limits:524288KB

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


华丽的分割线


解题思路

最小生成树(图)+最短路

考场上脑抽打了个二分直接T掉,因为一次堆优化Dij就要花我一秒多

根据题目要求,我们需要先求出使起点和终点相互联通时的最小温度值,那就先对温度值进行排序再不断加边直到联通,注意:应当要将联通时温度相同的那些边也加入生成图里面,否则很显然是错误的

然后在跑一边最短路就可以了,边权是这个边的温度值乘以时间,也就是获得的热量值

可以见巨丑的代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3f
#define maxn 800005
using namespace std;
struct Edge{
	ll index,s,t,nxt,temp;
	ll w;
}edge[maxn*4];
ll head[maxn],tot=0;
ll n,m,s,t;
ll dis[maxn],book[maxn];
priority_queue< pair<ll,ll> > hep;
void add(ll st,ll to,ll we,ll tmp){edge[tot].index=tot;edge[tot].s=st;edge[tot].t=to;edge[tot].temp=tmp;edge[tot].w=we;edge[tot].nxt=head[st];head[st]=tot;tot++;return;}
ll gmax(ll a,ll b){return a>b?a:b;}
ll gmin(ll a,ll b){return a<b?a:b;}
void check(ll tmp){
	memset(dis,0x3f,sizeof(dis));
	memset(book,0,sizeof(book));
	while(hep.size()) hep.pop();
	dis[s]=0;
	hep.push(make_pair(0,s));
	while(!hep.empty()){
		ll np=hep.top().second;
		hep.pop();
		if(!book[np]){
			book[np]=1;
			for(ll i=head[np];i!=-1;i=edge[i].nxt){
				if(edge[i].temp>tmp) continue;
				if(dis[edge[i].t]>dis[np]+edge[i].w){
					dis[edge[i].t]=dis[np]+edge[i].w;
					hep.push(make_pair(0-dis[edge[i].t],edge[i].t));
				}
			}
		}
	}
	printf("%lld %lld",tmp,dis[t]);
	//anst=tmp;
	//ansum=dis[t];
	return;
}
bool cmp(Edge a,Edge b){return a.temp<b.temp;}
bool cmp2(Edge a,Edge b){return a.index<b.index;}
ll gf(ll x){return book[x]==x?x:book[x]=gf(book[x]);}
int main(){
	freopen("running.in","r",stdin);
	freopen("running.out","w",stdout);
	memset(head,-1,sizeof(head));
	scanf("%lld %lld",&n,&m);
	//n=rd();m=rd();
	for(ll i=1;i<=m;i++){
		ll a,b,c,d;
		scanf("%lld %lld %lld %lld",&a,&b,&c,&d);
		//a=rd();b=rd();c=rd();d=rd();
		add(a,b,c*d,c);
		add(b,a,c*d,c);
	}
	scanf("%lld %lld",&s,&t);
	for(ll i=1;i<=n;i++)
		book[i]=i;
	//s=rd();t=rd();
	sort(edge,edge+tot,cmp);
	ll lst=0;
	for(ll i=0;i<tot;i++){
		ll a=edge[i].s,b=edge[i].t;
		if(gf(a)!=gf(b)){
			book[gf(a)]=gf(b);
			lst=edge[i].temp;
		}
		if(gf(s)==gf(t)){
			break;
		}
	}
	sort(edge,edge+tot,cmp2);
	check(lst);
	return 0;
}

posted on 2018-08-17 09:54  theOldChun  阅读(182)  评论(0)    收藏  举报

导航