[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;
}