您的位置:首页 > 其它

[kuangbin带你飞]专题四 最短路练习 A-E

2017-09-05 20:44 495 查看
题目链接:https://vjudge.net/contest/66569#overview

A:

#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
const int maxn=1005;
vector <pair<int,int> >E[maxn];
int dis[maxn];
bool vis[maxn];
void Init()
{
for(int i=0;i<maxn;i++)
E[i].clear(),vis[i]=false,dis[i]=1e9;
}
void spfa(int s,int t)
{
queue<int>q;
q.push(s);
dis[s]=0;
vis[s]=true;
while(!q.empty())
{
int now=q.front();
q.pop();
vis[now]=false;
for(int i=0;i<E[now].size();i++)
{
int next=E[now][i].first;
if(dis[next]>dis[now]+E[now][i].second)
{
dis[next]=dis[now]+E[now][i].second;
if(vis[next])continue;
vis[next]=true;
q.push(next);
}
}
}
}
int main()
{
int T,N;
while(scanf("%d%d",&T,&N)==2)
{
Init();
for(int i=1;i<=T;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
E[x].push_back(make_pair(y,z));
E[y].push_back(make_pair(x,z));
}
spfa(N,1);
printf("%d\n",dis[1]);
}
return 0;
}


B:最短路的变形,求最小边.数据小,可以写个floyd交.

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
double map[205][205];
int x[205];
int y[205];
double  dis(int i,int j)
{
return sqrt(double(x[i]-x[j])*(x[i]-x[j])+double(y[i]-y[j])*(y[i]-y[j]));
}
void floyd(int n)
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
map[i][j]=min(map[i][j],max(map[i][k],map[k][j]));
}
int main()
{
int n,q=1;
while(scanf("%d",&n)==1&&n)
{
memset(map,0x3f,sizeof(map));
for(int i=1; i<=n; i++)
scanf("%d%d",&x[i],&y[i]);
for(int i=1; i<=n; i++)
for(int j=i+1; j<=n; j++)
map[i][j]=map[j][i]=dis(i,j);
floyd(n);
printf("Scenario #%d\nFrog Distance = %.3f\n\n",q++,map[1][2]);
}
}


C:就是B题的反过来,求最大的边。但是floyd过不了,用了我的dij模版改了下条件。dis[next]=max(dis[next],min(dis[now],cost[now][next])

#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=1005; //顶点数自己定
vector <pair<int,int> >E[maxn];//存图
int dis[maxn];
void Init()
{
for(int i=0;i<maxn;i++)
E[i].clear(),dis[i]=0;
}
void Dijkstra(int s,int t)//源点,终点.
{
priority_queue<pair<int,int> >q;
dis[1]=1e9;
q.push(make_pair(dis[1],1));
while(!q.empty())
{
int now=q.top().second;
q.pop();
for(int i=0;i<E[now].size();i++)
{
int next=E[now][i].first;
if(dis[next]<min(dis[now],E[now][i].second))
{
dis[next]=min(dis[now],E[now][i].second);
q.push(make_pair(dis[next],next));
}
}
}
}

int main()
{
int t;
int n,m;
int cas=1;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
Init();
for(int i=0;i<m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
E[x].push_back(make_pair(y,z));
E[y].push_back(make_pair(x,z));
}
Dijkstra(1,n);
printf("Scenario #%d:\n",cas++);
printf("%d\n",dis
);
if(t!=0)
printf("\n");

}
return 0;
}

D:n个源点,1个x目标点.单源找来回最大的最短路. 回来只要找一次,出发每个点找一次.

#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1005;
vector<pair<int,int> >E[maxn];
int dis[maxn];
int go[maxn];
void dij(int s)
{
for(int i=0;i<maxn;i++)
dis[i]=1e9;
dis[s]=0;
priority_queue<pair<int,int> >q;
q.push(make_pair(-dis[s],s));
while(!q.empty())
{
int now=q.top().second;
q.pop();
for(int i=0;i<E[now].size();i++)
{
int next=E[now][i].first;
if(dis[next]>dis[now]+E[now][i].second)
{
dis[next]=dis[now]+E[now][i].second;
q.push(make_pair(-dis[next],next));
}
}
}
}
int main()
{
int n,m,x;
scanf("%d%d%d",&n,&m,&x);
for(int i=0;i<m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
E[x].push_back(make_pair(y,z));
}
for(int i=1;i<=n;i++)
{
if(n==x)continue;
dij(i),go[i]=dis[x];
}
dij(x);
int ans=-1;
for(int i=1;i<=n;i++)
ans=max(ans,go[i]+dis[i]);
printf("%d\n",ans);
}


E:读这种长的英文是真烦,

第一行叫你输4个数 N,M,S,V . N种货币种类(用数字代替) M个城市(每个城市有两种货币可以进行兑换) S(你的钱的种类) V(你的钱数)

接下来M行自然就是6个数代表该城市的信息:货币A,货币B,A->B的汇率,A->B的佣金,B->A的汇率,B->A的佣金.(题目有给兑换公式)

问你有没办法通过一系列货币的转换,最后当货币换回原来货币种类的时候,V变多了。 事实上就是判断正环的问题。那就改下判断负环的一些条件就好了。改下初始值

初始d(S)=V   而源点到其他店的距离(权值)初始化为无穷小(0),当s到其他某点的距离能不断变大时,说明存在最大路径,用BF判断是第n次循环还变大就有正环,spfa就是入队超过n次说明有正环,这里我用spfa做。。

#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <cstdio>
using namespace std;
const int maxn=105;
int n,m,s;
double v;
struct exc{
double r,c;
};
vector<pair<int,exc> >E[maxn];
double dis[maxn];
bool vis[maxn];
int time[maxn];
bool spfa()
{
for(int i=0;i<maxn;i++) vis[i]=false;
for(int i=0;i<maxn;i++)	dis[i] = 0;
for(int i=0;i<maxn;i++)	time[i]= 0;
dis[s]=v;
vis[s]=true;
queue<int>q;
q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop();
time[now]++;
vis[now]=false;
if(time[now]>n) return true;
for(int i=0;i<E[now].size();i++)
{
int next=E[now][i].first;
double temp=0;
temp=(dis[now]-E[now][i].second.c)*(E[now][i].second.r);
if(dis[next]<temp)
{
dis[next]=temp;
if(vis[next])continue;
vis[next]=true;
q.push(next);
}
}
}
return false;
}

int main()
{
scanf("%d%d%d%lf",&n,&m,&s,&v);
for(int i=1;i<=m;i++)
{
int x,y;
double xyr,xyc,yxr,yxc;
scanf("%d%d%lf%lf%lf%lf",&x,&y,&xyr,&xyc,&yxr,&yxc);
exc temp;
temp.r=xyr,temp.c=xyc;
E[x].push_back(make_pair(y,temp));
temp.r=yxr,temp.c=yxc;
E[y].push_back(make_pair(x,temp));
}
printf("%s",spfa()?"YES":"NO");
}

剩下有空补,先去补其他知识.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: