最短路变形 nyoj1248、poj1797 dijkstra+堆优化
2017-07-05 18:29
225 查看
同款链接:点击打开链接
链接中的博客用的是dijkstra算法;可以顺利ac;
但是这两题的数据范围都不大,如果数据范围比较大呢,dijkstra算法就不能够顺利ac了,会超时!
所以这篇博客就是用的dijkstra+堆优化的算法;
nyoj 1248:
题意:好像是中文;
思路:每个询问给出a、b,要求找到a-b的哪条路上的最大值是最小的,输出这个最小值;
代码:
poj 1797:
题意:解释以下样例:1-3有两条路,(1):1-2-3 最大承重为3;(2):1-3最大承重为4;所以输出1-3的最大承重为4;
思路:一个简单的dijk变形;但是我写了一个多小时,这道题要求的是1-n的那条路的最小值是最大的;那么求最大值就要給cost[]赋初值为最小!
代码:
玲珑oj1126
题意:输入起点s,终点t,然后求从起点到终点的最小花费;一条路径的花费就是这条路径的最大边权;
思路:d[j]=min(max(d[s],cost[s][j]),d[j]); 这是题目的数据范围:第一行两个整数,N,M。满足(1 <= N <= 10^5, 0 <= M <= 5*10^5)接下来M行,每行三个整数U,V,C。表示有一个连接U点和V点的边,且边权是C。(1<=C<=10^9);所以只用dijkstra不能够解决,使用堆优化可以直接ac;
代码:
#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1000010;
struct qnode
{
int v,c;
bool operator < (const qnode &x)const
{
return x.c<c;//从大到小;
}
};
struct Edge
{
int v,cost;
};
vector<Edge>E[maxn];
bool vis[maxn];
int dis[maxn];
int s,t;
int n,m;
void dijk(int n,int start)
{
memset(vis,false,sizeof(vis));
for(int i=1; i<=n; i++) dis[i]=inf;
priority_queue<qnode>que;
while(!que.empty()) que.pop();
dis[s]=0;
que.push(qnode {start,0});
qnode tmp;
while(!que.empty())
{
tmp=que.top();
que.pop();
int u=tmp.v;
if(vis[u]) continue;
vis[u]=true;
for(int i=0; i<E[u].size(); i++)
{
int v=E[u][i].v;
int cost=E[u][i].cost;
int tt=cost;
if(u!=start&&dis[u]!=inf)
tt=max(dis[u],cost);
if(dis[v]>tt)
{
dis[v]=tt;
que.push(qnode {v,dis[v]});
}
}
}
if(dis[t]==inf) puts("-1");
else printf("%d\n",dis[t]);
}
void addedge(int u,int v,int w)
{
E[u].push_back(Edge {v,w});
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0; i<m; i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c);
addedge(v,u,c);
}
scanf("%d%d",&s,&t);
if(s==t)
{
printf("0\n");
return 0;
}
dijk(n,s);
return 0;
}
链接中的博客用的是dijkstra算法;可以顺利ac;
但是这两题的数据范围都不大,如果数据范围比较大呢,dijkstra算法就不能够顺利ac了,会超时!
所以这篇博客就是用的dijkstra+堆优化的算法;
nyoj 1248:
题意:好像是中文;
思路:每个询问给出a、b,要求找到a-b的哪条路上的最大值是最小的,输出这个最小值;
代码:
#include<cstdio> #include<cmath> #include<vector> #include<cstring> #include<algorithm> #include<queue> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const int maxn=1000010; struct qnode { int v,c; bool operator < (const qnode &x)const { return x.c<c;//从大到小; } }; struct Edge { int v,cost; }; vector<Edge>E[maxn]; bool vis[maxn]; int dis[maxn]; int s,t; int n,m; //更改变量! void dijk(int n,int start) { memset(vis,false,sizeof(vis)); for(int i=1; i<=n; i++) dis[i]=inf; priority_queue<qnode>que; while(!que.empty()) que.pop(); dis[s]=0; que.push(qnode {start,0}); qnode tmp; while(!que.empty()) { tmp=que.top(); que.pop(); int u=tmp.v; if(vis[u]) continue; vis[u]=true; for(int i=0; i<E[u].size(); i++) { int v=E[u][i].v; int cost=E[u][i].cost; int tt=cost; // if(u!=start)//flag// tt=max(dis[u],cost); if(dis[v]>tt) { dis[v]=tt; que.push(qnode {v,dis[v]}); } } } if(dis[t]==inf) puts("-1"); else printf("%d\n",dis[t]); } void addedge(int u,int v,int w) { E[u].push_back(Edge {v,w}); } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=0; i<m; i++) { int u,v,c; scanf("%d%d%d",&u,&v,&c); // if(E[u][v].c<c) // continue; addedge(u,v,c); addedge(v,u,c); } int Q; scanf("%d",&Q); while(Q--) { scanf("%d%d",&s,&t); if(s==t) { printf("0\n"); continue; } dijk(n,s); } return 0; }
poj 1797:
题意:解释以下样例:1-3有两条路,(1):1-2-3 最大承重为3;(2):1-3最大承重为4;所以输出1-3的最大承重为4;
思路:一个简单的dijk变形;但是我写了一个多小时,这道题要求的是1-n的那条路的最小值是最大的;那么求最大值就要給cost[]赋初值为最小!
代码:
#include<cstdio> #include<cmath> #include<vector> #include<cstring> #include<algorithm> #include<queue> using namespace std; typedef long long ll; #define inff -0x3f3f3f3f const int maxn=1010; struct qnode { int v,c; bool operator < (const qnode &x)const { return x.c>c;//从小到大; } }; struct Edge { int v,cost; }; vector<Edge>E[maxn]; bool vis[maxn]; int dis[maxn]; int s,t; int n,m; void dijk(int n,int start) { memset(vis,false,sizeof(vis)); for(int i=1; i<=n; i++) dis[i]=inff; priority_queue<qnode>que; while(!que.empty()) que.pop(); dis[s]=0; que.push(qnode {start,0}); qnode tmp; while(!que.empty()) { tmp=que.top(); que.pop(); int u=tmp.v; if(vis[u]) continue; vis[u]=true; for(int i=0; i<E[u].size(); i++) { int v=E[u][i].v; int cost=E[u][i].cost; int tt=cost; if(u!=start&&dis[u]!=inff)//flag// tt=min(dis[u],cost); if(dis[v]<tt) { dis[v]=tt; que.push(qnode {v,dis[v]}); } } } printf("%d\n",dis ); } void addedge(int u,int v,int w) { E[u].push_back(Edge {v,w}); } int main() { int n,m; int t,co=1; scanf("%d",&t); while(t--) { for(int i=0;i<=maxn;i++) E[i].clear(); scanf("%d%d",&n,&m); for(int i=0; i<m; i++) { int u,v,c; scanf("%d%d%d",&u,&v,&c); // if(E[u][v].c<c) // continue; addedge(u,v,c); addedge(v,u,c); } printf("Scenario #%d:\n",co); if(n==1) { printf("0\n"); continue; } else dijk(n,1); printf("\n"); co++; } return 0; }//注意:多组输入一定要清空数组,这里是vector数组!
玲珑oj1126
题意:输入起点s,终点t,然后求从起点到终点的最小花费;一条路径的花费就是这条路径的最大边权;
思路:d[j]=min(max(d[s],cost[s][j]),d[j]); 这是题目的数据范围:第一行两个整数,N,M。满足(1 <= N <= 10^5, 0 <= M <= 5*10^5)接下来M行,每行三个整数U,V,C。表示有一个连接U点和V点的边,且边权是C。(1<=C<=10^9);所以只用dijkstra不能够解决,使用堆优化可以直接ac;
代码:
#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1000010;
struct qnode
{
int v,c;
bool operator < (const qnode &x)const
{
return x.c<c;//从大到小;
}
};
struct Edge
{
int v,cost;
};
vector<Edge>E[maxn];
bool vis[maxn];
int dis[maxn];
int s,t;
int n,m;
void dijk(int n,int start)
{
memset(vis,false,sizeof(vis));
for(int i=1; i<=n; i++) dis[i]=inf;
priority_queue<qnode>que;
while(!que.empty()) que.pop();
dis[s]=0;
que.push(qnode {start,0});
qnode tmp;
while(!que.empty())
{
tmp=que.top();
que.pop();
int u=tmp.v;
if(vis[u]) continue;
vis[u]=true;
for(int i=0; i<E[u].size(); i++)
{
int v=E[u][i].v;
int cost=E[u][i].cost;
int tt=cost;
if(u!=start&&dis[u]!=inf)
tt=max(dis[u],cost);
if(dis[v]>tt)
{
dis[v]=tt;
que.push(qnode {v,dis[v]});
}
}
}
if(dis[t]==inf) puts("-1");
else printf("%d\n",dis[t]);
}
void addedge(int u,int v,int w)
{
E[u].push_back(Edge {v,w});
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0; i<m; i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c);
addedge(v,u,c);
}
scanf("%d%d",&s,&t);
if(s==t)
{
printf("0\n");
return 0;
}
dijk(n,s);
return 0;
}
相关文章推荐
- 【最短路】变形-- nyoj 1248 海岛争霸、poj 1797 Heavy Transportation
- POJ 1797Heavy Transportation +第七届河南省程序设计大赛NYOJ1248 海岛争霸 (最小生成树变形/djs变形)
- POJ 3013 Big Christmas Tree【最短路变形,DIjkstra堆优化+spfa算法】
- poj 1797(最短路变形)
- POJ 2253 Frogger【最短路变形——路径上最小的最大权】
- POJ 2253 Frogger 最短路-Dijkstra的变形形式
- POJ 2253 Frogger 最短路-Dijkstra的变形形式
- POJ 2253 Frogger(最短路的变形)
- poj 1860 Currency Exchange (最短路变形-spfa)
- poj 1797(最短路变形)
- POJ3635 周游诸城:变形的SPFA/Dijkstra最短路+动规思想+Heap
- poj 1135 最短路(优先队列堆优化Dijkstra实现)
- 最短路变形_Poj_2253
- POJ - 3268 Silver Cow Party (往返最短路,Floyd,Dijkstra 2次优化)
- POJ 2253 Frogger -- 最短路变形
- POJ 2253 Frogger【最短路变形——路径上最小的最大权】
- poj 2263 Heavy Cargo 最短路 变形
- poj 3013 Big Christmas Tree 最短路变形
- POJ 3635 Full Tank? (最短路变形,BFS+优先队列)
- poj 1797 最短路变形