您的位置:首页 > 其它

BZOJ2763, 最短路

2015-12-10 19:43 253 查看
好激动,没想到,我在BZOJ这个网站AC的第一道是一个最短路的,虽然仔细一想也不是很难。

简单说一下吧!之所以开始做这道题还是想练一下最短路,因为刚重温了一下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 MB
Submit: 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 1

0 4

0 1 5

1 2 5

2 3 5

3 4 5

2 3 3

0 2 100

Sample Output

8
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: