ccf20170304地铁修建_Solution

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

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

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

1.并查集

 #include <stdio.h>
#include <stdlib.h>
#define maxn 100000
#define maxm 200000 //并查集 UnionFind
//171s struct node
{
long x,y,len;
}; long father[maxn+]; long cmp(const void *a,const void *b)
{
return (*(struct node *)a).len-(*(struct node *)b).len;
} long getfather(long d)
{
if (father[d]==d)
return d;
father[d]=getfather(father[d]);
return father[d];
} int main()
{
long n,m,i,u,v;
struct node *road=(struct node *) malloc (sizeof(struct node)*(maxm+));
scanf("%ld%ld",&n,&m);
for (i=;i<=m;i++)
scanf("%ld%ld%ld",&road[i].x,&road[i].y,&road[i].len);
qsort(&road[],m,sizeof(struct node),cmp);
for (i=;i<=n;i++)
father[i]=i;
//边从小到大 加入图中,直到1到n可达
//每次加边(x,y) father[y]=x
for (i=;i<=m;i++)
{
u=getfather(road[i].x);
v=getfather(road[i].y);
father[v]=u; //每一次判断1,n的父亲是否相同,如果是,即1到n可达
if (getfather(father[])==getfather(father[n]))
break;
}
//即1到n必经过该边i,而该边长度最长
printf("%ld\n",road[i].len);
return ;
}

2.Spfa(循环队列)

 #include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
#define maxn 100000
#define maxm 200000
#define maxc 1000000 long max(long a,long b)
{
if (a>b)
return a;
else
return b;
} int main()
{
struct node
{
long d,len;
struct node *next;
};
long n,m,head,tail,d,value,i,a,b,c;
long *dis=(long *) malloc (sizeof(long)*(maxn+));
//循环队列
long *line=(long *) malloc (sizeof(long)*(maxn+));
bool *vis=(bool *) malloc (sizeof(bool)*(maxn+));
//本身已经是struct node *point,创建数组再加"*"
struct node **point=(struct node **) malloc (sizeof(struct node *)*(maxn+));
struct node *t;
scanf("%ld%ld",&n,&m); for (i=;i<=n;i++)
{
point[i]=NULL;
//1 ≤ c ≤ 1000000
//max<=c
dis[i]=maxc;
vis[i]=true;
}
for (i=;i<=m;i++)
{
scanf("%ld%ld%ld",&a,&b,&c);
//build a
t=(struct node *) malloc (sizeof(struct node));
t->d=b;
t->len=c;
if (point[a]!=NULL)
t->next=point[a];
else
t->next=NULL;
point[a]=t;
//build b
t=(struct node *) malloc (sizeof(struct node));
t->d=a;
t->len=c;
if (point[b]!=NULL)
t->next=point[b];
else
t->next=NULL;
point[b]=t;
}
dis[]=;
vis[]=false;
line[]=;
//head=front-1 牺牲一个位置 front为队列头位置
head=;
tail=;
//这里的循环队列不用判断空或者溢出
//因为如果那样的话,已经不能用了。
//不存在空的情况。而数组要开的足够大,使队列不溢出。
while (head!=tail)
{
//head++;
//队列为0~n
head++;
if (head==n+)
head=;
d=line[head];
t=point[d];
while (t)
{
if (dis[d]<t->len)
value=t->len;
else
value=dis[d];
if (value<dis[t->d])
{
dis[t->d]=value;
//如果该点未被放在队列里,则入队;否则不入队
//即在队列里的点都不重复
//则队列(tail-head)最多有n+1个数(n个点+空位置(head))
if (vis[t->d])
{
//tail++;
tail++;
if (tail==n+)
tail=;
line[tail]=t->d;
vis[t->d]=false;
}
}
t=t->next;
}
vis[d]=true;
}
printf("%ld\n",dis[n]);
return ;
}

3.dijkstra(80 Points)

 #include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
#define maxn 100000
#define maxm 200000
#define maxc 1000000
#define maxdist 1000000000 //裸dijkstra 80分 超时 long max(long a,long b)
{
if (a>b)
return a;
else
return b;
} int main()
{
struct node
{
long d,len;
struct node *next;
};
struct node **point=(struct node **) malloc (sizeof(struct node *)*(maxn+));
struct node *p;
bool *vis=(bool *) malloc (sizeof(bool)*(maxn+));
long *dist=(long *) malloc (sizeof(long)*(maxn+));
long n,m,i,j,a,b,c,d,value,mindist;
scanf("%ld%ld",&n,&m);
for (i=;i<=n;i++)
{
point[i]=NULL;
dist[i]=maxc;
vis[i]=true;
}
for (i=;i<=m;i++)
{
scanf("%ld%ld%ld",&a,&b,&c);
//build a
p=(struct node *) malloc (sizeof(struct node));
p->d=b;
p->len=c;
if (point[a]!=NULL)
p->next=point[a];
else
p->next=NULL;
point[a]=p;
//build b
p=(struct node *) malloc (sizeof(struct node));
p->d=a;
p->len=c;
if (point[b]!=NULL)
p->next=point[b];
else
p->next=NULL;
point[b]=p;
}
for (i=;i<=n;i++)
{
vis[i]=true;
dist[i]=maxdist;
}
//从点1开始
dist[]=;
d=;
vis[]=false;
for (i=;i<n;i++)
{
p=point[d];
while (p)
{
if (dist[d]<p->len)
value=p->len;
else
value=dist[d];
if (value<dist[p->d])
dist[p->d]=value;
p=p->next;
}
mindist=maxdist;
for (j=;j<=n;j++)
if (vis[j] && dist[j]<mindist)
{
mindist=dist[j];
d=j;
}
//从点n结束
if (d==n)
break;
vis[d]=false;
}
printf("%ld\n",dist[n]);
//最小堆优化
return ;
}

4.dijkstra堆优化

 #include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
#define maxn 100000
#define maxm 200000
#define maxc 1000000
#define maxdist 1000000000 //裸dijkstra 80分 超时 long max(long a,long b)
{
if (a>b)
return a;
else
return b;
} int main()
{
struct node
{
long d,len;
struct node *next;
};
struct node **point=(struct node **) malloc (sizeof(struct node *)*(maxn+));
struct node *p;
bool *vis=(bool *) malloc (sizeof(bool)*(maxn+));
long *dist=(long *) malloc (sizeof(long)*(maxn+));
long n,m,i,j,a,b,c,d,value,mindist;
scanf("%ld%ld",&n,&m);
for (i=;i<=n;i++)
{
point[i]=NULL;
dist[i]=maxc;
vis[i]=true;
}
for (i=;i<=m;i++)
{
scanf("%ld%ld%ld",&a,&b,&c);
//build a
p=(struct node *) malloc (sizeof(struct node));
p->d=b;
p->len=c;
if (point[a]!=NULL)
p->next=point[a];
else
p->next=NULL;
point[a]=p;
//build b
p=(struct node *) malloc (sizeof(struct node));
p->d=a;
p->len=c;
if (point[b]!=NULL)
p->next=point[b];
else
p->next=NULL;
point[b]=p;
}
for (i=;i<=n;i++)
{
vis[i]=true;
dist[i]=maxdist;
}
//从点1开始
dist[]=;
d=;
vis[]=false;
for (i=;i<n;i++)
{
p=point[d];
while (p)
{
if (dist[d]<p->len)
value=p->len;
else
value=dist[d];
if (value<dist[p->d])
dist[p->d]=value;
p=p->next;
}
mindist=maxdist;
for (j=;j<=n;j++)
if (vis[j] && dist[j]<mindist)
{
mindist=dist[j];
d=j;
}
//从点n结束
if (d==n)
break;
vis[d]=false;
}
printf("%ld\n",dist[n]);
//最小堆优化
return ;
}

csp20170304地铁修建_Solution的更多相关文章

  1. CCF CSP 201703-4 地铁修建

    博客中的文章均为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201703-4 地铁修建   问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n ...

  2. CSP 201703-4 地铁修建 最小生成树+并查集

    地铁修建   试题编号: 201703-4 试题名称: 地铁修建 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力, ...

  3. CSP 201703-4 地铁修建【最小生成树+并查集】

    问题描述 试题编号: 201703-4 试题名称: 地铁修建 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市 ...

  4. ccf 201703-4 地铁修建(95)(并查集)

    ccf 201703-4 地铁修建(95) 使用并查集,将路径按照耗时升序排列,依次加入路径,直到1和n连通,这时加入的最后一条路径,就是所需要修建的时间最长的路径. #include<iost ...

  5. CCF(地铁修建):向前星+dijikstra+求a到b所有路径中最长边中的最小值

    地铁修建 201703-4 这题就是最短路的一种变形,不是求两点之间的最短路,而是求所有路径中的最长边的最小值. 这里还是使用d数组,但是定义不同了,这里的d[i]就是表示从起点到i的路径中最长边中的 ...

  6. CSP 地铁修建 Kruskal (最小生成树+并查集)

    问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁. 地铁由很多段隧道组成,每段隧道连接两个交通枢纽.经过勘探,有m段隧道作为候选,两个交通 ...

  7. CCF地铁修建

    问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁. 地铁由很多段隧道组成,每段隧道连接两个交通枢纽.经过勘探,有m段隧道作为候选,两个交通 ...

  8. CCF 201703-4 地铁修建(最小生成树)

    题意:A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁.地铁由很多段隧道组成,每段隧道连接两个交通枢纽.经过勘探,有m段隧道作为候选,两个交通枢纽之 ...

  9. 【CCF】地铁修建 改编Dijkstra

    [题意] 给定有n个点,m条边的无向图,没有平行边和自环,求从1到n的路径中,最长段的最小值(最短路不再是路径和,而是所有段中的最大值) [AC] #include<iostream> # ...

随机推荐

  1. Aop笔记

    参考: https://blog.csdn.net/bombSKLK/article/details/79143145 示例 拦截的 注解的方法 @Around("@annotation(c ...

  2. 如何新增一个ssh-key文件

    前言 由于在公司有一个sshkey 在用,用于绑定公司的git code 仓库.那么在家要连上git hub 仓库,就也需要一个 ssh key .为了避免公司信息外露,所以还是新增一个ssh key ...

  3. HDU-6440-费马小定理

    亏我前几天还学数论呢...没有深入研究费马小定理这个东西...做事情一定要静下心来啊... 题目要求满足(m+n)^p=m^p+n^p,要你定义一个封闭的新的加法和乘法运算 我们知道费马小定理中有两种 ...

  4. 终于做完了这个pj

    首先要说这个博客网站实在是功能太弱!不知道为什么还要每次写博客.直接交作业不好吗- -b 1.估计时间: 看见这个任务就觉得很难啊,估计装vs2012就得半天,然后上学期选修的c++基本上都忘光了,本 ...

  5. linux内核分析第四次实验

    实验步骤: 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用.本次实验中我使用第20号系统调用getpid()函数,用于取得进程识别码. C代码(getpid.c): #include ...

  6. 第三个Sprint ------第四天

    出题代码 package com.app.senior_calculator; import java.io.Serializable; public class Question implement ...

  7. Docker for windows WIN版本,主板特性问题

    WIN 10 Home版无法开启Hyper-V特性. Docker for windows有Hyper-V和VirtualBox两个版本: https://forums.docker.com/t/in ...

  8. “一战通offer”互联网实习季编程挑战

    1.字符串变形 对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形.首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把 ...

  9. python decimal.quantize()参数rounding的各参数解释与行为

    我最开始其实是由于疑惑ROUND_FLOOR和 ROUND_DOWN的表现区别才看了一波文档,但是感觉拉出一票以前没有留意过的东西. 贴一个decimal文档里面的解释: ROUND_CEILING ...

  10. 关于python 自带csv库的使用心得 附带操作实例以及excel下乱码的解决

    因为上次帮我们产品处理过一个文件,他想生成能excel处理操作的.但是上次由于时间非常紧张,所以并没有处理好. 正好无聊就来好好研究一下 ,找算法要了几个 csv文件.来好好玩一玩. 全篇使用了pyt ...