您的位置:首页 > 其它

最短路变形 nyoj1248、poj1797 dijkstra+堆优化

2017-07-05 18:29 225 查看
同款链接:点击打开链接

链接中的博客用的是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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dijkstra