zoukankan      html  css  js  c++  java
  • csp20170304地铁修建_Solution

    ccf20170304地铁修建_Solution

    这里最短路为所以从点1到点n的路径中最长的道路的长度。

    因为1 ≤ n ≤ 100000,1 ≤ m ≤ 200000,属于稀疏图,所以使用Spfa(循环队列)较适合,如果使用dijkstra需要堆优化。

     

    其实这道题用并查集最好,对所有道路长度从小到大排序,依次添加道路,直到点1和点n相连(属于同一个集合)。

    1.并查集

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define maxn 100000
     4 #define maxm 200000
     5 
     6 //并查集 UnionFind
     7 //171s
     8 
     9 struct node
    10 {
    11     long x,y,len;
    12 };
    13 
    14 long father[maxn+1];
    15 
    16 long cmp(const void *a,const void *b)
    17 {
    18     return (*(struct node *)a).len-(*(struct node *)b).len;
    19 }
    20 
    21 long getfather(long d)
    22 {
    23     if (father[d]==d)
    24         return d;
    25     father[d]=getfather(father[d]);
    26     return father[d];
    27 }
    28 
    29 int main()
    30 {
    31     long n,m,i,u,v;
    32     struct node *road=(struct node *) malloc (sizeof(struct node)*(maxm+1));
    33     scanf("%ld%ld",&n,&m);
    34     for (i=1;i<=m;i++)
    35         scanf("%ld%ld%ld",&road[i].x,&road[i].y,&road[i].len);
    36     qsort(&road[1],m,sizeof(struct node),cmp);
    37     for (i=1;i<=n;i++)
    38         father[i]=i;
    39     //边从小到大 加入图中,直到1到n可达
    40     //每次加边(x,y) father[y]=x
    41     for (i=1;i<=m;i++)
    42     {
    43         u=getfather(road[i].x);
    44         v=getfather(road[i].y);
    45         father[v]=u;
    46 
    47         //每一次判断1,n的父亲是否相同,如果是,即1到n可达
    48         if (getfather(father[1])==getfather(father[n]))
    49             break;
    50     }
    51     //即1到n必经过该边i,而该边长度最长
    52     printf("%ld
    ",road[i].len);
    53     return 0;
    54 }

    2.Spfa(循环队列)

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <malloc.h>
      4 #include <stdbool.h>
      5 #define maxn 100000
      6 #define maxm 200000
      7 #define maxc 1000000
      8 
      9 long max(long a,long b)
     10 {
     11     if (a>b)
     12         return a;
     13     else
     14         return b;
     15 }
     16 
     17 int main()
     18 {
     19     struct node
     20     {
     21         long d,len;
     22         struct node *next;
     23     };
     24     long n,m,head,tail,d,value,i,a,b,c;
     25     long *dis=(long *) malloc (sizeof(long)*(maxn+1));
     26     //循环队列
     27     long *line=(long *) malloc (sizeof(long)*(maxn+1));
     28     bool *vis=(bool *) malloc (sizeof(bool)*(maxn+1));
     29     //本身已经是struct node *point,创建数组再加"*"
     30     struct node **point=(struct node **) malloc (sizeof(struct node *)*(maxn+1));
     31     struct node *t;
     32     scanf("%ld%ld",&n,&m);
     33 
     34     for (i=1;i<=n;i++)
     35     {
     36         point[i]=NULL;
     37         //1 ≤ c ≤ 1000000
     38         //max<=c
     39         dis[i]=maxc;
     40         vis[i]=true;
     41     }
     42     for (i=1;i<=m;i++)
     43     {
     44         scanf("%ld%ld%ld",&a,&b,&c);
     45         //build a
     46         t=(struct node *) malloc (sizeof(struct node));
     47         t->d=b;
     48         t->len=c;
     49         if (point[a]!=NULL)
     50             t->next=point[a];
     51         else
     52             t->next=NULL;
     53         point[a]=t;
     54         //build b
     55         t=(struct node *) malloc (sizeof(struct node));
     56         t->d=a;
     57         t->len=c;
     58         if (point[b]!=NULL)
     59             t->next=point[b];
     60         else
     61             t->next=NULL;
     62         point[b]=t;
     63     }
     64     dis[1]=0;
     65     vis[1]=false;
     66     line[1]=1;
     67     //head=front-1 牺牲一个位置 front为队列头位置
     68     head=0;
     69     tail=1;
     70     //这里的循环队列不用判断空或者溢出
     71     //因为如果那样的话,已经不能用了。
     72     //不存在空的情况。而数组要开的足够大,使队列不溢出。
     73     while (head!=tail)
     74     {
     75         //head++;
     76         //队列为0~n
     77         head++;
     78         if (head==n+1)
     79             head=0;
     80         d=line[head];
     81         t=point[d];
     82         while (t)
     83         {
     84             if (dis[d]<t->len)
     85                 value=t->len;
     86             else
     87                 value=dis[d];
     88             if (value<dis[t->d])
     89             {
     90                 dis[t->d]=value;
     91                 //如果该点未被放在队列里,则入队;否则不入队
     92                 //即在队列里的点都不重复
     93                 //则队列(tail-head)最多有n+1个数(n个点+空位置(head))
     94                 if (vis[t->d])
     95                 {
     96                     //tail++;
     97                     tail++;
     98                     if (tail==n+1)
     99                         tail=0;
    100                     line[tail]=t->d;
    101                     vis[t->d]=false;
    102                 }
    103             }
    104             t=t->next;
    105         }
    106         vis[d]=true;
    107     }
    108     printf("%ld
    ",dis[n]);
    109     return 0;
    110 }

    3.dijkstra(80 Points)

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <malloc.h>
     4 #include <stdbool.h>
     5 #define maxn 100000
     6 #define maxm 200000
     7 #define maxc 1000000
     8 #define maxdist 1000000000
     9 
    10 //裸dijkstra 80分 超时
    11 
    12 long max(long a,long b)
    13 {
    14     if (a>b)
    15         return a;
    16     else
    17         return b;
    18 }
    19 
    20 int main()
    21 {
    22     struct node
    23     {
    24         long d,len;
    25         struct node *next;
    26     };
    27     struct node **point=(struct node **) malloc (sizeof(struct node *)*(maxn+1));
    28     struct node *p;
    29     bool *vis=(bool *) malloc (sizeof(bool)*(maxn+1));
    30     long *dist=(long *) malloc (sizeof(long)*(maxn+1));
    31     long n,m,i,j,a,b,c,d,value,mindist;
    32     scanf("%ld%ld",&n,&m);
    33     for (i=1;i<=n;i++)
    34     {
    35         point[i]=NULL;
    36         dist[i]=maxc;
    37         vis[i]=true;
    38     }
    39     for (i=1;i<=m;i++)
    40     {
    41         scanf("%ld%ld%ld",&a,&b,&c);
    42         //build a
    43         p=(struct node *) malloc (sizeof(struct node));
    44         p->d=b;
    45         p->len=c;
    46         if (point[a]!=NULL)
    47             p->next=point[a];
    48         else
    49             p->next=NULL;
    50         point[a]=p;
    51         //build b
    52         p=(struct node *) malloc (sizeof(struct node));
    53         p->d=a;
    54         p->len=c;
    55         if (point[b]!=NULL)
    56             p->next=point[b];
    57         else
    58             p->next=NULL;
    59         point[b]=p;
    60     }
    61     for (i=1;i<=n;i++)
    62     {
    63         vis[i]=true;
    64         dist[i]=maxdist;
    65     }
    66     //从点1开始
    67     dist[1]=0;
    68     d=1;
    69     vis[1]=false;
    70     for (i=1;i<n;i++)
    71     {
    72         p=point[d];
    73         while (p)
    74         {
    75             if (dist[d]<p->len)
    76                 value=p->len;
    77             else
    78                 value=dist[d];
    79             if (value<dist[p->d])
    80                 dist[p->d]=value;
    81             p=p->next;
    82         }
    83         mindist=maxdist;
    84         for (j=2;j<=n;j++)
    85             if (vis[j] && dist[j]<mindist)
    86             {
    87                 mindist=dist[j];
    88                 d=j;
    89             }
    90         //从点n结束
    91         if (d==n)
    92             break;
    93         vis[d]=false;
    94     }
    95     printf("%ld
    ",dist[n]);
    96     //最小堆优化
    97     return 0;
    98 }

    4.dijkstra堆优化

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <malloc.h>
     4 #include <stdbool.h>
     5 #define maxn 100000
     6 #define maxm 200000
     7 #define maxc 1000000
     8 #define maxdist 1000000000
     9 
    10 //裸dijkstra 80分 超时
    11 
    12 long max(long a,long b)
    13 {
    14     if (a>b)
    15         return a;
    16     else
    17         return b;
    18 }
    19 
    20 int main()
    21 {
    22     struct node
    23     {
    24         long d,len;
    25         struct node *next;
    26     };
    27     struct node **point=(struct node **) malloc (sizeof(struct node *)*(maxn+1));
    28     struct node *p;
    29     bool *vis=(bool *) malloc (sizeof(bool)*(maxn+1));
    30     long *dist=(long *) malloc (sizeof(long)*(maxn+1));
    31     long n,m,i,j,a,b,c,d,value,mindist;
    32     scanf("%ld%ld",&n,&m);
    33     for (i=1;i<=n;i++)
    34     {
    35         point[i]=NULL;
    36         dist[i]=maxc;
    37         vis[i]=true;
    38     }
    39     for (i=1;i<=m;i++)
    40     {
    41         scanf("%ld%ld%ld",&a,&b,&c);
    42         //build a
    43         p=(struct node *) malloc (sizeof(struct node));
    44         p->d=b;
    45         p->len=c;
    46         if (point[a]!=NULL)
    47             p->next=point[a];
    48         else
    49             p->next=NULL;
    50         point[a]=p;
    51         //build b
    52         p=(struct node *) malloc (sizeof(struct node));
    53         p->d=a;
    54         p->len=c;
    55         if (point[b]!=NULL)
    56             p->next=point[b];
    57         else
    58             p->next=NULL;
    59         point[b]=p;
    60     }
    61     for (i=1;i<=n;i++)
    62     {
    63         vis[i]=true;
    64         dist[i]=maxdist;
    65     }
    66     //从点1开始
    67     dist[1]=0;
    68     d=1;
    69     vis[1]=false;
    70     for (i=1;i<n;i++)
    71     {
    72         p=point[d];
    73         while (p)
    74         {
    75             if (dist[d]<p->len)
    76                 value=p->len;
    77             else
    78                 value=dist[d];
    79             if (value<dist[p->d])
    80                 dist[p->d]=value;
    81             p=p->next;
    82         }
    83         mindist=maxdist;
    84         for (j=2;j<=n;j++)
    85             if (vis[j] && dist[j]<mindist)
    86             {
    87                 mindist=dist[j];
    88                 d=j;
    89             }
    90         //从点n结束
    91         if (d==n)
    92             break;
    93         vis[d]=false;
    94     }
    95     printf("%ld
    ",dist[n]);
    96     //最小堆优化
    97     return 0;
    98 }
  • 相关阅读:
    约瑟夫环问题
    String常用的工具类
    java 中的==和equals的深度解析
    Intellij IDEA的一些常用设置和使用小技巧
    jvm内存模型概述
    springcloud开篇
    oracle生成path的sql语句
    oracle表空间异常大
    springboot2集成activiti出错
    策略模式2
  • 原文地址:https://www.cnblogs.com/cmyg/p/6816470.html
Copyright © 2011-2022 走看看