http://ac.jobdu.com/problem.php?pid=1162  I Wanna Go Home

方法一:普通的dijkstra

/*
很明显的最短路,但关键是如何建图。可以看到,一共只有两种走法,一种是从city1出发,一直走属于group1的city直到city2,或者一直走属于group2的city直到city1。我昨天建了两个图来表示两种情况,分别求最短路,然后取小的,结果越写越乱。今天发现其实一次就可以,只要在建图的时候,如果两个city属于一个group,就建双向图,否则就建从属于group1的city到属于group2的city的单向图。原因很简单,因为两种情况都不会出现从2到1的情况。建好图然后就简单了,注意无解的情况。
*/
#include<iostream>
#include<cstdio>
using namespace std;
#include<memory.h>int map[601][601],x[601];
int dijkstra(int n,int start,int end)   //start是原点,n是图中所有点的个数
{int visit[601];    //判断是否已存入该点到visit集合中int i,j,k,min,t;for (i=1;i<=n;i++){x[i]=map[start][i];visit[i]=0;   //初始都未用过该点}x[start]=0;visit[start]=1;// 依次将未放入visit集合的结点中,取x[]最小值的结点,放入集合visit中// 一旦visit包含了所有顶点,x就记录了从源点到所有其他顶点之间的最短路径长度// 注意是从第二个节点开始,第一个为源点for(i=2;i<=n;i++){min = 16843009;t=-1;// 找出当前未使用的点j的x[j]最小值for(j=1; j<=n; ++j){if(!visit[j] && x[j]<min){t = j;              // t保存当前邻接点中距离最小的点的号码min = x[j];}}if(t!=-1){visit[t] = 1;    // 将t点存入visit集合中// 更新x的值for(j=1; j<=n; ++j){if (!visit[j] && min+map[t][j]<x[j])x[j]=min+map[t][j];}}}if(x[end]<16843009)return x[end];elsereturn -1;
}
int main(void)
{int i,j,n,m,from,to,cost,group[601];while(scanf("%d",&n),n){scanf("%d",&m);for(i=1;i<=n;i++){for(j=1;j<=n;j++){if(i==j)map[i][j]=0;elsemap[i][j]=16843009;}}//memset(map,1,sizeof(map));for(i=0;i<m;i++){scanf("%d %d %d",&from,&to,&cost);if(cost<map[from][to])map[from][to]=map[to][from]=cost;}for(i=1;i<=n;i++)scanf("%d",&group[i]);for(i=1;i<n;i++){for(j=i+1;j<=n;j++){if(group[i]==group[j])      //如果是一个group,不用管continue;else if(group[i]==1 && group[j]==2)      //如果一个是1一个是2,则建单向边 map[j][i]=16843009;else if(group[i]==2 && group[j]==1)      //如果一个是1一个是2,则建单向边 map[i][j]=16843009;}}printf("%d\n",dijkstra(n,1,2));}return 0;
}

方法二:优先队列+邻接表 来实现dijkstra算法

/*
优先队列+邻接表 来实现dijkstra算法
根据下面的那个模板来修改过来的
*/
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
#include<memory.h>#define INF 16843009
#define MAXN 601  //结点的个数typedef struct Edge
{int adj;struct Edge *next;int cost;
}Edge,*pEdge;
Edge edge[MAXN];typedef struct Heap
{bool operator <(Heap T)const{return T.dis<dis;}int x;int dis;
}Heap;struct Node
{int from,to,cost;
}node[10001];void insert_adjlist(int a,int b, int c)    //创建邻接表
{pEdge p,q;p=&edge[a];    while(p->next!=NULL)p=p->next;q=new Edge;q->adj=b;q->next=NULL;q->cost=c;p->next=q;
}int dijkstra(int n,int start,int end)   //start是原点,n是图中所有点的个数
{int i,x[MAXN];bool visit[MAXN];Heap cur,in;pEdge p;memset(visit,false,sizeof(visit));for(i=1;i<=n;i++)x[i]=INF;priority_queue< Heap >q;  //优先级队列cur.x=start;cur.dis=0;x[start]=0;q.push(cur);while(!q.empty()){cur = q.top();q.pop();if(cur.x == end)    //找到终点return cur.dis;if(visit[cur.x])   //访问过continue;visit[cur.x]=true;p=edge[cur.x].next;while(p!=NULL){if(!visit[p->adj]){in.x=p->adj;in.dis=cur.dis+p->cost;if(in.dis<x[in.x]){x[in.x]=in.dis;q.push(in);}}p=p->next;}}return -1;
}int main(void)
{int i,j,n,m,from,to,group[601];while(scanf("%d",&n),n){scanf("%d",&m);for(i=1;i<=n;i++)edge[i].next=NULL;for(i=0;i<m;i++){scanf("%d %d %d",&node[i].from,&node[i].to,&node[i].cost);   //暂时保存起来}for(i=1;i<=n;i++)scanf("%d",&group[i]);for(i=0;i<m;i++){from=node[i].from;to=node[i].to;if(group[from]==group[to])      //如果是一个group,建立双向边{insert_adjlist(from,to,node[i].cost);insert_adjlist(to,from,node[i].cost); }else if(group[from]==1 && group[to]==2)      //如果一个是1一个是2,则建单向边insert_adjlist(from,to,node[i].cost);else if(group[from]==2 && group[to]==1)      //如果一个是1一个是2,则建单向边insert_adjlist(to,from,node[i].cost); }printf("%d\n",dijkstra(n,1,2));}return 0;
}

http://acm.hdu.edu.cn/showproblem.php?pid=2544 最短路

//优先队列+邻接表 来实现dijkstra算法(模板)
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
#include<memory.h>#define INF 16843009
#define MAXN 601  //结点的个数typedef struct Edge
{int adj;struct Edge *next;int cost;
}Edge,*pEdge;
Edge edge[MAXN];typedef struct Heap
{bool operator <(Heap T)const{return T.dis<dis;}int x;int dis;
}Heap;void insert_adjlist(int a,int b, int c)    //创建邻接表
{pEdge p,q;p=&edge[a];    while(p->next!=NULL)p=p->next;q=new Edge;q->adj=b;q->next=NULL;q->cost=c;p->next=q;
}int dijkstra(int n,int start,int end)   //start是原点,n是图中所有点的个数
{int i,x[MAXN];bool visit[MAXN];Heap cur,in;pEdge p;memset(visit,false,sizeof(visit));for(i=1;i<=n;i++)x[i]=INF;priority_queue< Heap >q;  //优先级队列cur.x=start;cur.dis=0;x[start]=0;q.push(cur);while(!q.empty()){cur = q.top();q.pop();if(cur.x == end)return cur.dis;if(visit[cur.x])continue;visit[cur.x]=true;p=edge[cur.x].next;while(p!=NULL){if(!visit[p->adj]){in.x=p->adj;in.dis=cur.dis+p->cost;if(in.dis<x[in.x]){x[in.x]=in.dis;q.push(in);}}p=p->next;}}return -1;
}int main(void)
{int i,j,n,m,from,to,cost,group[601];while(scanf("%d %d",&n,&m),n+m){for(i=1;i<=n;i++)edge[i].next=NULL;for(i=0;i<m;i++){scanf("%d %d %d",&from,&to,&cost);insert_adjlist(from,to,cost);insert_adjlist(to,from,cost); }printf("%d\n",dijkstra(n,1,n));}return 0;
}

2011年北京大学计算机研究生机试真题(dijkstra+优先队列)相关推荐

  1. 2010年北京大学计算机研究生机试真题

    http://ac.jobdu.com/problem.php?pid=1149   子串计算 #include<iostream> #include<cstdio> #inc ...

  2. 2011年吉林大学计算机研究生机试真题

    http://ac.jobdu.com/problem.php?pid=1107     搬水果 方法一:(优先队列) #include<iostream> #include<que ...

  3. 211大学计算机复试不机试,复试机试之上海交通大学计算机研究生机试真题.doc...

    复试机试之上海交通大学计算机研究生机试真题 (你自己回去改格式啊,这个有多重繁杂字体,你自己改好看点~~还有知识05年到11年的)复试机试之2011年上海交通大学计算机研究生机试真题 (2012-02 ...

  4. 2000年华中科技大学计算机研究生机试真题 对称矩阵

    题目1180:对称矩阵 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2518 解决:1295 题目描述: 输入一个N维矩阵,判断是否对称. 输入: 输入第一行包括一个数:N(1<= ...

  5. 上海交大研究生计算机考研真题,2011年上海交通大学计算机研究生机试真题

    Oracle 约束(constraint)的几个参数的小研究 ORACLE中,约束分deferred 跟 immediate 2种: deferred:如果 Oracle 在事务提交(commit)时 ...

  6. 2011年上海交通大学计算机研究生机试真题

    http://ac.jobdu.com/problem.php?pid=1103 二次方程计算器 #include<iostream> #include<cstdio> #in ...

  7. 最大公约数 [2011年哈尔滨工业大学计算机研究生机试真题]

    题目描述> 输入两个正整数,求其最大公约数. 输入描述: 测试数据有多组,每组输入两个正整数. 输出描述: 对于每组输入,请输出其最大公约数. 样例输入: 49 14 样例输出: 7 解题思路: ...

  8. 进制转换 [2008年北京大学图形实验室计算机研究生机试真题]

    题目描述: 求任意两个不同进制非负整数的转换(2进制-16进制),所给整数在long所能表达的范围之内. 不同进制的表示符号为(0,1,-,9,a,b,-,f)或者(0,1,-,9,A,B,-,F). ...

  9. 2005年上海交通大学计算机研究生机试真题

    http://ac.jobdu.com/problem.php?pid=1090   路径打印 #include<iostream> #include<set> #includ ...

最新文章

  1. web前端培训:本期教程CSS 三大特性
  2. php file_get_contents遇到https的处理办法
  3. linux收发十六进制工具,linux下的十六进制编辑器---wxHexEdit
  4. S5PV210开发 -- USB 你知道多少?(一)
  5. 如何使用Gradle外部脚本进行项目构建
  6. python 100days github_GitHub - rghwer/Python-100-Days: Python - 100天从新手到大师
  7. 关于miniconda的安装,配置以及包批量安装和使用
  8. 开源贡献 计算_学生如何开始为开源软件做贡献
  9. ASP.NET MVC Action返回结果类型【转】
  10. php自定义函数指定参数类型,php – Doctrine:如何添加带可选参数的自定义函数?...
  11. php中传址调用,PHP中foreach引用传地址
  12. LeetCode Sparse Matrix Multiplication
  13. 易语言大漠进行字库制作的时候出现不能展示二值化区域
  14. 国赛培训——最优化智能算法——模拟退火
  15. sklearn make_blobs函数
  16. pythonwhile嵌套if_python中for、while循环、if嵌套的使用
  17. MSDC 4.3 接口规范(13)
  18. 30%自媒体从业者才知道的爆款标题的专用模板,封面图的文案同样适用。
  19. 优化elelment ui 的 dialog 样式
  20. 选择一个手持式频谱分析仪 需要参考哪些条件

热门文章

  1. 问题 F: 分盒子(经典)
  2. sprintf的使用(和为n的回文数)
  3. 投稿 | “轻量应用服务器”征文活动正式启动
  4. 阿里云函数计算 FC再次荣获最受观众喜爱奖
  5. Flink集成Iceberg在同程艺龙的实践
  6. mysql 按照in id顺序_Mysql查询结果顺序按in()中ID的顺序排列的案例区分
  7. Python基础——PyCharm版本——第五章、循环(for、while、break、continue)
  8. 一个Java程序是怎样运行起来的【class解析全过程】
  9. Ajax的get与post的区别,什么时候使用post?
  10. 用户 NT AUTHORITY\NETWORK SERVICE 登录失败解决方法