• 【BZOJ 3482】 3482: [COCI2013]hiperprostor (dij+凸包)


    3482: [COCI2013]hiperprostor

    Time Limit: 20 Sec  Memory Limit: 256 MB
    Submit: 277  Solved: 81

    Description

    在遥远的未来,行星之间的食品运输将依靠单向的贸易路线。每条路径直接连接两个行星,且其运输时间是已知的
    。贸易商协会打算利用一项最近发现的新技术——超空间旅行,以增加一些新的航线。通过超空间旅行的航线也是
    单向的。由于该项技术仍处于试验阶段,超空间旅行的时间目前是未知的,但它不取决于行星之间的距离,所以每
    个超空间旅行的路线将花费等量的时间。下图是三个相互联通的行星及其运输时间的例子。行星使用正整数标号,
    超空间旅行时间记为“x”(图片对应第输入样例):过境的时间以天计,并且始终是一个正整数。贸易商协会希
    望对引进新航线的后果进行分析:对于某两个行星A和B,他们想知道对于任意的x,从A到B的最短路径的总中转时
    间的所有可能的值。例如,在上述情况中,从星球2到星球1的最短路径所需时间可以取值5(如果x≥5),4,3,2
    ,或1天(如果x<5)

    Input

    输入的第一行包含两个整数P和R,分别代表行星的数目和航线数量,1≤P≤500,0≤R≤10000。接下来的R条航线
    路径包含两或三个整数:行星标号C和D(1≤C,D≤P,C≠D),和T,从C到D的旅行时间。对于传统的路径,T是一
    个整数(1≤T≤1000000),超空间航线中,T是字符“x”。 可以存在多行有两个相同的行星。下面的行中包含的
    整数Q(1≤Q≤10),表示查询的数量。以下Q行包含两个整数星球标号(A和B,A≠B),为贸易商协会的查询:“
    从A到B的最短路径时间的可能值是什么?

    Output

    输出必须包含q行,每行??一个查询。每一行都必须包含两个整数:不同的可能值的数目和它们的总和。如果不同
    的可能值的数目是无限的,该行只输出“inf”。如果没有从A到B的路径,不同的可能值的数目及它们的总和都是0

    Sample Input

    4 4
    1 2 x
    2 3 x
    3 4 x
    1 4 8
    3
    2 1
    1 3
    1 4

    Sample Output

    0 0
    inf
    3 17

    HINT

     2016.6.15新加数据一组,未重测

    Source

    【分析】

      f[i][j]表示走到i,走了j条x边,最短路。【好像spfa会被卡,我就打了dij

      【dij的比较没有打return 调了半天哭死。。。

      若f[i][j]全是INF 就是无解

      若f[i][0]是INF 就是无穷解

      然后其他的,得到i,f[i][ed],写成直线y=i*x+f[i][ed],维护一个凸包。

      他们中间点的个数和值是等差数列,直接求和。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 510
      9 #define Maxm 10010
     10 #define LL long long
     11 #define INF 0x7fffffff
     12 
     13 int n,m;
     14 
     15 int read()
     16 {
     17     char ch;
     18     while(!(((ch=getchar())>='0'&&ch<='9')||(ch=='x')));
     19     if(ch=='x') return 0;
     20     int x=ch-'0';
     21     while(((ch=getchar())>='0')&&(ch<='9')) x=x*10+ch-'0';
     22     return x;
     23 }
     24 
     25 struct node
     26 {
     27     int x,y,next,c;
     28 }t[Maxm*2];
     29 int len,first[Maxn];
     30 
     31 void ins(int x,int y,int c)
     32 {
     33     t[++len].x=x;t[len].y=y;t[len].c=c;
     34     t[len].next=first[x];first[x]=len;
     35 }
     36 
     37 struct hp
     38 {
     39     int x,y,dis;
     40     friend bool operator < (hp x,hp y)
     41     {
     42         return x.dis>y.dis;
     43     }
     44 };
     45 
     46 int f[Maxn][Maxn];
     47 priority_queue<hp> q;
     48 void dij(int st)
     49 {
     50     hp nw;nw.dis=0;nw.x=st;nw.y=0;
     51     q.push(nw);f[st][0]=0;
     52     while(!q.empty())
     53     {
     54         nw=q.top();q.pop();
     55         if(nw.dis>f[nw.x][nw.y]) continue;
     56         int x=nw.x;
     57         hp now;
     58         for(int i=first[x];i;i=t[i].next)
     59         {
     60             int y=t[i].y;
     61             if(t[i].c==0)
     62             {
     63                 if(nw.y==n) continue;
     64                 now.x=y;now.y=nw.y+1;now.dis=nw.dis;
     65                 if(f[now.x][now.y]>f[nw.x][nw.y])
     66                 {
     67                     f[now.x][now.y]=f[nw.x][nw.y];
     68                     q.push(now);
     69                 }
     70             }
     71             else
     72             {
     73                 now.x=y;now.y=nw.y;now.dis=f[nw.x][nw.y]+t[i].c;
     74                 if(f[now.x][now.y]>f[nw.x][nw.y]+t[i].c)
     75                 {
     76                     f[now.x][now.y]=f[nw.x][nw.y]+t[i].c;
     77                     q.push(now);
     78                 }
     79             }
     80         }
     81     }
     82 }
     83 struct Line
     84 {
     85     double k,b; 
     86     Line() {}
     87     Line(double nk,double nb) {k=nk;b=nb;}
     88 }P[Maxn];int sl;double tt[Maxn];  
     89  
     90 double pt(double k1,double b1,double k2,double b2)
     91 {
     92     return (b2-b1)/(k1-k2); 
     93 }
     94 
     95 void get_ans()
     96 {
     97     int q=read();int cnt=0;
     98     while(q--)
     99     {
    100         int st=read(),ed=read();
    101         for(int i=1;i<=n;i++)
    102          for(int j=0;j<=n;j++) {f[i][j]=INF;}
    103         dij(st);
    104         bool pp=0;
    105         for(int i=0;i<=n;i++) if(f[ed][i]!=INF) {pp=1;break;}
    106         if(!pp) {printf("0 0
    ");continue;}
    107         if(f[ed][0]==INF) {printf("inf
    ");continue;}
    108         int num=0;
    109         LL sum=0;sl=0; 
    110         for(int i=n;i>=0;i--)
    111         {
    112             if(f[ed][i]==INF) continue; 
    113             while(sl>=1&&pt(P[sl].k,P[sl].b,i,f[ed][i])<=tt[sl]) sl--;
    114             P[++sl]=Line(i,f[ed][i]);
    115             if(sl>1) tt[sl]=pt(P[sl-1].k,P[sl-1].b,P[sl].k,P[sl].b); 
    116         }
    117         for(int i=1;i<=sl-1;i++)
    118         {
    119             int l=(int)tt[i]+1,r=(int)tt[i+1];
    120             if(l<=r) sum+=(LL)(l*P[i].k+P[i].b+r*P[i].k+P[i].b)*(r-l+1)/2;
    121         }
    122         num=(int)tt[sl];
    123         if(tt[sl]!=num||sl==1) num++,sum+=f[ed][0];
    124         printf("%d %lld
    ",num,sum);
    125     }
    126 }
    127 
    128 int main()
    129 {
    130     n=read();m=read();
    131     len=0;
    132     memset(first,0,sizeof(first));
    133     for(int i=1;i<=m;i++)
    134     {
    135         int x,y,c;
    136         x=read();y=read();c=read();
    137         ins(x,y,c);
    138     }
    139     get_ans();
    140     return 0;
    141 }
    View Code

    【凸包和dij都好弱啊,膜了一下某大神代码。。】

    2017-03-31 08:17:57

  • 相关阅读:
    [NHibernate]第一个NHibernate的应用配置
    [NHibernate]利用LINQPad查看NHibernate生成SQL语句
    [NHibernate]查看NHibernate生成的SQL语句
    Twitter的分布式自增ID雪花算法snowflake (Java版)
    雪花算法:生成分布式全局唯一ID
    数据加密共享与签名方案
    Java 8中处理集合的优雅姿势——Stream
    消息中间件选型分析——从Kafka与RabbitMQ的对比来看全局
    从概念到底层技术,一文看懂区块链架构设计(附知识图谱)
    以太坊源码分析——BlockChain
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6649492.html
Copyright © 2020-2023  润新知