zoukankan      html  css  js  c++  java
  • 10.28T1 排序+最短路

    2、做运动 5109

    sport

    【问题描述】

      一天,Y君在测量体重的时候惊讶的发现,由于常年坐在电脑前认真学习,她的体重有了突飞猛进的增长。
      幸好Y君现在退役了,她有大量的时间来做运动,她决定每天从教学楼跑到食堂来减肥。
      Y君将学校中的所有地点编号为1到n,其中她的教学楼被编号为S,她的食堂被编号为T,学校中有m条连接两个点的双向道路,保证从任意一个点可以通过道路到达学校中的所有点。
      然而Y君不得不面临一个严峻的问题,就是天气十分炎热,如果Y君太热了,她就会中暑。
      于是Y君调查了学校中每条路的温度t,及通过一条路所需的时间c。Y君在温度为t的地方跑单位时间,就会使她的热量增加t。
      由于热量过高Y君就会中暑,而且Y君也希望在温度较低的路上跑,她希望在经过的所有道路中最高温度最低的前提下,使她到达食堂时的热量最低 (从教学楼出发时,Y君的热量为0)。
      请你帮助Y君设计从教学楼到食堂的路线,以满足她的要求。你只需输出你设计的路线中所有道路的最高温度和Y君到达食堂时的热量。

    【输入格式】

      第一行由一个空格隔开的两个正整数n,m,代表学校中的地点数和道路数。
      接下来m行,每行由一个空格隔开的四个整数a,b,t,c 分别代表双向道路的两个端点,温度和通过所需时间。
      最后一行由一个空格隔开的两个正整数S,T,代表教学楼和食堂的编号。
      注意:输入数据量巨大,请使用快速的读入方式。

    【输出格式】

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

    【输入样例】

    5 6

    1 2 12

    2 32 2

    34 3 4

    4 5 3 5

    1 3 4 1

    3 5 3 6

    1 5

    【输出样例】

    3 24

    【数据规模与约定】
      10%的数据满足t=0
      另外10%的数据满足c=0
      另外30%的数据满足n≤2000
      100%的数据满足n≤500000,m≤1000000,0≤t≤10000,0≤c≤10^8,1≤a,b,S,T≤n,S≠T

    考虑将所有边按温度从小到大排序加入图中,同时用并查集维护 S 和 T 的连通性。

    如果加入某些边之后 S 和 T 联通了,那么跑一遍 S 到 T 的最短路即可得到答案。

    注意温度相等的边要一起加入图中。

    时间复杂度 O(mlogm)

    code:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<queue>
      4 #include<cstring>
      5 #include<algorithm>
      6 #define N 7000005
      7 typedef long long LL;
      8 using namespace std;
      9 struct node {
     10     int u,v;
     11     int c,t;
     12     LL w;
     13 } e[N],t[N];
     14 int first[N],nxt[N],cnt;
     15 void add(int u,int v,long long c,long long t) {
     16     e[++cnt].u=u;
     17     e[cnt].v=v;
     18     e[cnt].w=c*t;
     19     nxt[cnt]=first[u];
     20     first[u]=cnt;
     21 }
     22 int fa[N];
     23 long long find(long long x) {
     24     if(x!=fa[x])return fa[x]=find(fa[x]);
     25     return fa[x];
     26 }
     27 void merge(long long x,long long y) {
     28     long long f1=find(x),f2=find(y);
     29     if(f1!=f2) {
     30         fa[f1]=f2;
     31     }
     32 }
     33 bool cmp(node a,node b) {
     34     if(a.t==b.t)return a.c<b.c;
     35     return a.t<b.t;
     36 }
     37 long long n,m;
     38 int S,T;
     39 int max0=0;
     40 void kruskal() {
     41     int cnt_=0;
     42     for(int i=1; i<=m; i++) {
     43         int u=t[i].u,v=t[i].v;
     44         if(find(S)!=find(T)) {
     45             merge(u,v);
     46             add(u,v,t[i].c,t[i].t);
     47             add(v,u,t[i].c,t[i].t);
     48             max0=max(max0,t[i].t);
     49             if(find(S)==find(T)){
     50                 int now=i+1;
     51                 while(t[now].t==t[i].t){
     52                     add(t[now].u,t[now].v,t[now].c,t[now].t);
     53                     add(t[now].v,t[now].u,t[now].c,t[now].t);
     54                     now++;
     55                 }
     56                 break;
     57             }
     58         }
     59     }
     60 }
     61 long long dis[N];
     62 int vis[N];
     63 void spfa() {
     64     queue<int>q;
     65     memset(dis,0x3f3f3f3f,sizeof dis);
     66     memset(vis,0,sizeof vis);
     67     dis[S]=0;
     68     vis[S]=1;
     69     q.push(S);
     70     while(!q.empty()){
     71         int u=q.front();
     72         q.pop();
     73         vis[u]=0;
     74         for(int i=first[u];i;i=nxt[i]){
     75             int v=e[i].v;
     76             if(dis[v]>dis[u]+e[i].w){
     77                 dis[v]=dis[u]+e[i].w;
     78                 if(!vis[v]){
     79                     vis[v]=1;
     80                     q.push(v);
     81                 }
     82             }
     83         }
     84     }
     85 }
     86 int read(){
     87     int x=0,f=1;
     88     char c=getchar();
     89     while(!isdigit(c)){
     90         if(c=='-')f=-1;
     91         c=getchar();
     92     }
     93     while(isdigit(c)){
     94         x=(x<<3)+(x<<1)+c-'0';
     95         c=getchar();
     96     }
     97     return x*f;
     98 }
     99 int main() {
    100 //    freopen("running1.in","r",stdin);
    101     n=read(),m=read();
    102     for(int i=1; i<=n; i++)fa[i]=i;
    103     for(int i=1; i<=m; i++) {
    104         t[i].u=read(),t[i].v=read(),t[i].t=read(),t[i].c=read();
    105     }
    106     S=read(),T=read();
    107     sort(t+1,t+m+1,cmp);
    108     kruskal();
    109     spfa();
    110     cout<<max0<<" "<<dis[T];
    111     return 0;
    112 }

    over

  • 相关阅读:
    hdu 3714 Error Curves(三分)
    hdu 4717 The Moving Points(第一个三分题)
    hdu 4722 Good Numbers(规律题)
    分布式平台基础算法浅析
    Linux下通过管道杀死所有与tomcat相关的进程
    实习番外篇:解决C语言使用Makefile无法实现更好的持续集成问题
    SHELL脚本之awk妙用
    如何在CentOS7上安装Python3及对应问题
    欧拉定理和费马小定理
    最大公约和最小公倍数
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9864487.html
Copyright © 2011-2022 走看看