标签:screen 研究生 double sha field 输出 map dia ges
枚举中间点起点终点,对整个图进行松弛操作,就能得到整个图的多源最短路径;
Input
Output
Sample Input
3 USDollar BritishPound FrenchFranc 3 USDollar 0.5 BritishPound BritishPound 10.0 FrenchFranc FrenchFranc 0.21 USDollar 3 USDollar BritishPound FrenchFranc 6 USDollar 0.5 BritishPound USDollar 4.9 FrenchFranc BritishPound 10.0 FrenchFranc BritishPound 1.99 USDollar FrenchFranc 0.09 BritishPound FrenchFranc 0.19 USDollar 0
Sample Output
Case 1: Yes Case 2: No
Source
#include <iostream> #include <cstdio> #include <map> using namespace std; const int maxn=35; int n,m; map<string,int> N; double dis[maxn][maxn]; int main() { int kase=1; //freopen("Atext.in","r",stdin); while(cin >> n,n) { string a,b; double tmp; bool flag=false; for(int i=0;i<n;i++) for(int j=0;j<n;j++) dis[i][j]=-1; for(int i=0;i<n;i++){ cin >> a; N.insert(make_pair(a,i)); } cin >> m; for(int i=0;i<m;i++) { cin >> a >> tmp >> b; dis[N[a]][N[b]]=tmp; //邻接矩阵存边的信息; } for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j&&j!=k&&k!=i&&dis[i][k]!=-1&&dis[k][j]!=-1) dis[i][j]=max(dis[i][k]*dis[k][j],dis[i][j]); /*for(int i=0;i<n;i++) { for(int j=0;j<n;j++) cout << dis[i][j] << " "; cout << endl; } cout << endl;*/ for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(dis[i][j]*dis[j][i]>1)flag=1; printf("Case %d: %s\n",kase,flag?"Yes":"No"); N.clear(); kase++; } return 0; }
例:POJ2253 Frogger
Description
Input
Output
Sample Input
2 0 0 3 4 3 17 4 19 4 18 5 0
Sample Output
Scenario #1 Frog Distance = 5.000 Scenario #2 Frog Distance = 1.414
Source
#include <iostream> #include <cmath> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int maxn=205; struct node{ int x,y; }N[maxn]; int con[maxn][maxn],n; double G[maxn][maxn]; void floyed() //枚举所有边进行松弛; { for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) //松弛为最大边的最小值; G[i][j]=min(G[i][j],max(G[i][k],G[k][j])); } int main() { int kase=0; while(~scanf("%d",&n),n) { for(int i=0;i<n;i++) scanf("%d%d",&N[i].x,&N[i].y); for(int i=0;i<n;i++) //这样对称的邻接矩阵只须计算一半 for(int j=i+1;j<n;j++) G[i][j]=G[j][i]=(double)sqrt(double(N[i].x-N[j].x)*(N[i].x-N[j].x)+double(N[i].y-N[j].y)*(N[i].y-N[j].y)); floyed(); printf("Scenario #%d\n",++kase); printf("Frog Distance = %.3lf\n\n",G[0][1]); } return 0; }
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int maxn=1005; const int inf=0x3f3f3f3f; int n; struct node{ int x,y; }N[maxn]; bool vis[maxn]; double G[maxn][maxn],d[maxn]; //邻接矩阵 void Dijkstra() { fill(vis,vis+n,false); fill(d,d+n,inf); d[0]=0; while(true) { int v=-1; for(int i=0;i<n;i++) if(!vis[i]&&(v==-1||d[i]<d[v])) //从尚未使用过的顶点中选取一个最小值; v=i; if(v==-1) break; vis[v]=true; for(int i=0;i<n;i++) d[i]=min(d[i],max(d[v],G[v][i])); //源点到各点的最长边的最小值; } } int main() { int kase=0; while(~scanf("%d",&n),n) { for(int i=0;i<n;i++) scanf("%d%d",&N[i].x,&N[i].y); for(int i=0;i<n;i++) //这样对称的邻接矩阵只须计算一半 for(int j=i+1;j<n;j++) G[i][j]=G[j][i]=(double)sqrt(double(N[i].x-N[j].x)*(N[i].x-N[j].x)+double(N[i].y-N[j].y)*(N[i].y-N[j].y)); Dijkstra(); printf("Scenario #%d\n",++kase); printf("Frog Distance = %.3f\n\n",d[1]); } return 0; }
队列优化的bellman-ford;
#include <iostream> #include <queue> #include <cstdio> #include <vector> using namespace std; const int maxn=205; const int inf=0x3f3f3f3f; typedef pair<int,int> p; vector<p>E[maxn];//邻接表; int n,m,d[maxn],inq[maxn]; //d[maxn]到源点的最短距离,inq[maxn]在队列里的元素; void init() { for(int i=0;i<n;i++)E[i].clear(); for(int i=0;i<n;i++)inq[i]=0; for(int i=0;i<n;i++)d[i]=inf; } void spfa(int x) { queue<int> que; que.push(x),d[x]=0,inq[x]=1; while(!que.empty()) { int now=que.front(); que.pop(); inq[now]=0; for(int i=0;i<E[now].size();i++) { int v=E[now][i].first; if(d[v]>d[now]+E[now][i].second) { d[v]=d[now]+E[now][i].second; if(inq[v]==0){ inq[v]=1; que.push(v); } } } } } int main() { while(~scanf("%d%d",&n,&m)) { init(); int a,b,c; for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); E[a].push_back(p(b,c)); E[b].push_back(p(a,c)); } scanf("%d%d",&a,&b); spfa(a); if(d[b]==inf) cout << -1 << endl; else cout << d[b] << endl; } return 0; }
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn=205; const int inf=0x3f3f3f3f; int n,m,maze[maxn][maxn]; void floyed() { for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j&&j!=k&&k!=i) maze[i][j]=min(maze[i][j],maze[i][k]+maze[k][j]); } int main() { while(~scanf("%d%d",&n,&m)) { int a,b,c; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(i!=j) maze[i][j]=inf; } for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); maze[a][b]=min(c,maze[a][b]);//处理解决重边问题; maze[b][a]=min(c,maze[b][a]); } scanf("%d%d",&a,&b); floyed(); if(maze[a][b]==inf) cout << -1 << endl; else cout << maze[a][b] <<endl; } return 0; }
//自我整理:最短路径的这三个算法,就像BFS一样;
//spfa:每次把发生更新的点作为当前到该点的最短路径,都入队列视为下一次遍历开始的源点;
//dijkstra:每次只取所有发生更新的点,即所有当前最短路径中里离源点最近的点作为下一次开始的源点,前面的值都视为已确定的最短路径
最短路(Floyed、Dijkstra、Bellman-Ford、SPFA)
标签:screen 研究生 double sha field 输出 map dia ges
原文地址:https://www.cnblogs.com/Cloud-king/p/8967966.html