[kuangbin带你飞]专题四 最短路练习 A-E
2017-09-05 20:44
495 查看
题目链接:https://vjudge.net/contest/66569#overview
A:
B:最短路的变形,求最小边.数据小,可以写个floyd交.
C:就是B题的反过来,求最大的边。但是floyd过不了,用了我的dij模版改了下条件。dis[next]=max(dis[next],min(dis[now],cost[now][next])
D:n个源点,1个x目标点.单源找来回最大的最短路. 回来只要找一次,出发每个点找一次.
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做。。
剩下有空补,先去补其他知识.
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"); }
剩下有空补,先去补其他知识.
相关文章推荐
- [kuangbin带你飞]专题四 最短路练习 -A - Til the Cows Come Home
- [kuangbin带你飞]专题四 最短路练习 P
- [kuangbin带你飞]专题四 最短路练习
- [kuangbin带你飞]专题四 最短路练习 B
- [kuangbin带你飞]专题四 最短路练习D
- 【算法系列学习】Dijkstra求最短路 [kuangbin带你飞]专题四 最短路练习 D - Silver Cow Party
- [kuangbin带你飞]专题四 最短路练习-E
- [kuangbin带你飞]专题四 最短路练习 E POJ 1860
- [kuangbin带你飞]专题四 最短路练习 B
- 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home
- [kuangbin带你飞]专题四 最短路练习 K POJ 3159
- 【算法系列学习】Dijkstra算法变形 [kuangbin带你飞]专题四 最短路练习
- [kuangbin带你飞]专题四 最短路练习 MN
- [kuangbin带你飞]专题四 最短路练习 S POJ 3169
- [kuangbin带你飞]专题四 最短路练习
- [kuangbin带你飞]专题四 最短路练习 -F
- [kuangbin带你飞]专题四 最短路练习 R
- [kuangbin带你飞]专题四 最短路练习 O LightOJ 1074
- [kuangbin带你飞]专题四 最短路练习 G MPI Maelstrom
- [kuangbin带你飞]专题四 最短路练习 A POJ 2387