BZOJ2763, 最短路
2015-12-10 19:43
253 查看
好激动,没想到,我在BZOJ这个网站AC的第一道是一个最短路的,虽然仔细一想也不是很难。
简单说一下吧!之所以开始做这道题还是想练一下最短路,因为刚重温了一下dijkstra。刚开始看到也是又蒙了,然后仔细一想,状态的转移应该不难,应该是分层进行的,不断地进行下一步决策。所以就把刘汝佳的dijkstra算法改了一下,用在这道题;
同学说,指针版能更快一些,就学着打了个指针版,加油,也不难。
Submit: 1462 Solved: 564
[Submit][Status][Discuss]
第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
简单说一下吧!之所以开始做这道题还是想练一下最短路,因为刚重温了一下dijkstra。刚开始看到也是又蒙了,然后仔细一想,状态的转移应该不难,应该是分层进行的,不断地进行下一步决策。所以就把刘汝佳的dijkstra算法改了一下,用在这道题;
#include<cstdio> #include<iostream> #include<queue> #include<vector> #include<cstring> #define rep(i,j,k) for(int i = j; i <= k; i++) #define maxn 10005 #define INF 0xfffffff; using namespace std; int n, s, t, k, m; int read() { int s = 0, t = 1; char c = getchar(); while( !isdigit(c) ){ if( c == '-' ) t = -1; c = getchar(); } while( isdigit(c) ){ s = s * 10 + c - '0'; c = getchar(); } return s * t; } struct heapnode{ int d, u, zhi; bool operator < (const heapnode& rhs) const{ return d > rhs.d; } }; struct edge{ int from, to, key; }; struct Dijkstra{ int n, k; vector<edge> edges; vector<int> q[maxn]; int d[maxn][15]; bool done[maxn][15]; void init(int n,int k) { this->n = n; this->k = k; rep(i,0,n-1){ q[i].clear(); } edges.clear(); } void dijkstra(int s) { rep(i,0,n-1) rep(j,0,k) d[i][j] = INF; rep(i,0,k) d[s][i] = 0; priority_queue<heapnode> Q; Q.push((heapnode){0,s,0}); memset(done,0,sizeof(done)); while( !Q.empty() ){ heapnode x = Q.top(); Q.pop(); int u = x.u; int zhi = x.zhi; if( done[u][zhi] ) continue; done[u][zhi] = 1; int s = q[u].size(); rep(i,0,s-1){ edge& x = edges[q[u][i]]; int y = x.to; if( d[y][zhi] > d[u][zhi] + x.key ){ d[y][zhi] = d[u][zhi] + x.key; Q.push((heapnode){d[y][zhi],y,zhi}); } if( d[y][zhi+1] > d[u][zhi] && zhi < k ){ d[y][zhi+1] = d[u][zhi]; Q.push((heapnode){d[y][zhi+1],y,zhi+1}); } } } } void add_edge(int x,int y,int key) { edges.push_back((edge){x,y,key}); edges.push_back((edge){y,x,key}); int m = edges.size(); q[x].push_back(m-2); q[y].push_back(m-1); } }; Dijkstra solver; int main() { n = read(), m = read(), xk = read(), s = read(), t = read(); solver.init(n,k); rep(i,1,m){ int x = read(), y = read(), key = read(); solver.add_edge(x,y,key); } solver.dijkstra(s); int ans = 0xfffffff; rep(i,0,k){ ans = min(solver.d[t][i],ans); } cout<<ans<<endl; return 0; }
同学说,指针版能更快一些,就学着打了个指针版,加油,也不难。
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #define rep(i,j,k) for(int i = j; i <= k; i++) #define maxn 10005 #define maxl 50003 #define clr(i,l) memset(i,l,sizeof(i)); using namespace std; int n, m, s, t, xk; int d[maxn][13] = {0}; int read() { int s = 0, t = 1; char c = getchar(); while( !isdigit(c) ){ if( c == '-' ) t = -1; c = getchar(); } while( isdigit(c) ){ s = s * 10 + c - '0'; c = getchar(); } return s * t; } struct edge{ int to, key; edge* next; }; struct heapnode{ int r, k, u; bool operator < (const heapnode& rhs) const{ return r > rhs.r; } }; priority_queue<heapnode> Q; edge edges[maxl*2]; edge* pt; edge* head[maxn]; void add_edge(int x,int y,int key) { pt->to = y; pt->key = key; pt->next = head[x]; head[x] = pt++; pt->to = x; pt->key = key; pt->next = head[y]; head[y] = pt++; } void dijkstra() { clr(d,127); clr(d[s],0); Q.push((heapnode){0,0,s}); while( !Q.empty() ){ heapnode x = Q.top(); Q.pop(); int u = x.u, k= x.k; if( x.r != d[u][k] ) continue; for( edge*i = head[u]; i ; i = i->next ){ int t = i->to; if( d[t][k] > d[u][k] + i->key ) { d[t][k] = d[u][k] + i->key; Q.push((heapnode){d[t][k],k,t}); } if( d[t][k+1] > d[u][k] && k < xk ){ d[t][k+1] = d[u][k]; Q.push((heapnode){d[t][k+1],k+1,t}); } } } } int main() { n = read(), m = read(), xk = read(), s = read(), t = read(); pt = edges; rep(i,1,m){ int x = read(), y = read(), key = read(); add_edge(x,y,key); } dijkstra(); int ans = 0xfffffff; rep(i,0,xk){ ans = min(ans,d[t][i]); } cout<<ans<<endl; return 0; }
2763: [JLOI2011]飞行路线
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1462 Solved: 564
[Submit][Status][Discuss]
Description
Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?Input
数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
Output
只有一行,包含一个整数,为最少花费。Sample Input
5 6 10 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
Sample Output
8相关文章推荐
- UVA—10817 Headmaster's Headache
- shopxx研究
- nginx location
- 使用9Patch图片作为背景
- Caffe 安装教程 (Mac OS)
- Cocoapods完整使用
- <原创>一串简单的代码牵扯出的session,cookie,$_session,$_cookie之间关系问题
- dbms_job和dbmsi_job
- Redhat7 安装mariadb(原mysql)
- java语言编程的30条建议
- 《代码大全》之表驱动法
- poj 3617
- 机器学习:各算法小结(3)
- CCF真题之Z字形扫描
- CentOs 编译php 遇到的一些问题
- ISBN
- 删除排序数组中的重复数字——LintCode
- mysql基础语句
- 关于cocos2dx的背景音乐和音效(3)
- Xcode7在运行包含HTTP协议的程序时报错解决方法 App Transport Security has blocked a cleartext HTTP (http)