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. linux系统最小化安装后的初始化脚本

    作为运维人员,经常会初始化系统,系统在安装过程中基本都会选择最小化安装,这样安装好的系统里会缺少很多环境. 下面分享一个系统安装后的初始化脚本: #!/bin/bash #系统时最小化安装的,这里要安 ...

  2. SpringMVC环境搭建——HelloWorld

    1.新建Maven Web 工程: 2.添加相关的依赖包(Spring MVC.tomcat插件等),具体的pom.xml文件如下 <project xmlns="http://mav ...

  3. BugPhobia终章篇章:学霸在线系统Beta阶段展示

    0x00 :序言 1 universe, 9 planets, 204 countries,809 islands, 7 seas, and i had the privilege to meet y ...

  4. 个人实验 github地址:https://github.com/quchengyu/cher

    一.实践目的 1.掌握类的定义,对象的创建. 2.掌握实现封装.继承.多态的方法,掌握各种修饰符的使用. 3.掌握将对象数组作为方法的参数和返回值. 4.掌握抽象类与接口的概念及实现,理解动态绑定机制 ...

  5. 正则表达式(java)

    概念: 正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念. 正则表通常被用来检索.替换那些符合某个模式( ...

  6. [BUAA2017软工]第1次个人项目 数独

    [BUAA软工]第1次作业 个人项目 数独 一.项目地址 github地址:https://github.com/BuaaAlen/sudoku 二.PSP表格 三.解题思路描述 在拿到这个题目时,我 ...

  7. 无需破解:Windows Server 2008 R2 至少免费使用 900天

    无需破解:Windows Server 2008 R2 至少免费使用 900天 2009年10月30日 星期五 02:10 1.首先安装后,有一个180天的试用期. 2.在180天试用期即将结束时,使 ...

  8. 【gridview增删改查】数据库查询后lodop打印

    ASP.NET中使用gridview可以很容易的把需要的数据动态显示在前台,还可以在表格里加入列进行增删改查,每次点击的时候重新加载数据,gridview也提供了分页等功能,还有一些模版让显示在前台的 ...

  9. BZOJ4502串——AC自动机(fail树)

    题目描述 兔子们在玩字符串的游戏.首先,它们拿出了一个字符串集合S,然后它们定义一个字 符串为“好”的,当且仅当它可以被分成非空的两段,其中每一段都是字符串集合S中某个字符串的前缀. 比如对于字符串集 ...

  10. windows7下GithubDesktop和极域学生客户端冲突导致无法正常打开解决方案

    [出现问题] 很悲伤,今天GithubDesktop打开直接报错导致无法开启 报错如下 我的天呢,你敢相信连原因都不给我,但是这特么怎么可能难道我呢! 打开系统日志查看原因最终找到罪魁祸首!!! 计算 ...