水水的floyd算法
最短路问题模板题
平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。
其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。
现在的任务是找出从一点到另一点之间的最短路径。
输入格式
共n+m+3行,其中:
第一行为整数n。
第2行到第n+1行(共n行),每行两个整数x和y,描述了一个点的坐标。
第n+2行为一个整数m,表示图中连线的个数。
此后的m行,每行描述一条连线,由两个整数i和j组成,表示第i个点和第j个点之间有连线。
最后一行:两个整数s和t,分别表示源点和目标点。
输出格式
仅一行,一个实数(保留两位小数),表示从s到t的最短路径长度。
样例
输入数据 1
5
0 0
2 0
2 2
0 2
3 1
5
1 2
1 3
1 4
2 5
3 5
1 5
输出数据 1
3.41
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include<bits/stdc++.h> using namespace std; int n,m,a[105][3],x,y,s,t; double f[105][105]; int main(){ cin>>n; for ( int i=1;i<=n;i++) cin>>a[i][1]>>a[i][2]; cin>>m; memset(f,0x7f, sizeof (f)); for ( int i=1;i<=n;i++) f[i][i]=0; for ( int i=1;i<=m;i++) { cin>>x>>y; f[x][y]=f[y][x]=sqrt(pow(a[x][1]-a[y][1],2)+pow(a[x][2]-a[y][2],2)); } cin>>s>>t; for ( int k=1;k<=n;k++) for ( int i=1;i<=n;i++) for ( int j=1;j<=n;j++) if (k!=i&&k!=j&&i!=j) if (f[i][k]+f[k][j]<f[i][j]) f[i][j]=f[i][k]+f[k][j]; printf( "%.2lf" ,f[s][t]); return 0; } |
最佳牧场
约翰拥有P(1<=P<=500)个牧场.
贝茜特别喜欢其中的F个.所有的牧场 由C(1 < C<=8000)条双向路连接,第i路连接着ai,bi,需要Ti(1<=Ti< 892)单 位时间来通过.
作为一只总想优化自己生活方式的奶牛,贝茜喜欢自己某一天醒来,到达所有那F个她喜欢的 牧场的平均需时最小.那她前一天应该睡在哪个牧场呢?请帮助贝茜找到这个最佳牧场.
img
Format
Input
第1行输入三个整数P,F C.
之后F行每行输入一个整数表示一个贝茜喜欢的牧场.
之后C行每行输入三个整数ai,bi,Ti,描述一条路.
Output
一个整数,满足题目要求的最佳牧场.如果有多个答案,输出编号最小的
Samples
输入数据 1
13 6 15
11
13
10
12
8
1
2 4 3
7 11 3
10 11 1
4 13 3
9 10 3
2 3 2
3 5 4
5 9 2
6 7 6
5 6 1
1 2 4
4 5 3
11 12 3
6 10 1
7 8 7
sol
在这个代码中,有两处标红的地方
如果两个都不加的话,则会出错
如果两个都加,或只加其中一个均无没问题。
原因在于
在出现上面这种环,则会跑出a自己到自己的距离为9,这个值是小于从前设定的a自己到自己为无限大的值
于是a自己到自己就为9了,这个与实际是不相符合的。
如果加上
1 2 | for ( int i=1;i<=n;i++) g[i][i]=0;则不会更新自环的边如果加上 |
1 | if (k!=i&&k!=j&&i!=j)也不会来算自环的值,后面因为又加了两者之间距离不能为无限大,所以也是对的。总结:图的初始化设置是非常重要的。 |
1 | <br><br> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include<bits/stdc++.h> using namespace std; int g[510][510],n,f,m,l[510],u,v,w,ans,mn=INT_MAX; int main() { scanf( "%d%d%d" ,&n,&f,&m); //n个点,m边条, memset(g,63, sizeof (g)); int inf=g[1][1]; for ( int i=1;i<=f;i++) scanf( "%d" ,&l[i]); for ( int i=1;i<=m;i++) scanf( "%d%d%d" ,&u,&v,&w),g[u][v]=g[v][u]=w; for ( int i=1;i<=n;i++) g[i][i]=0; for ( int k=1;k<=n;k++) for ( int i=1;i<=n;i++) for ( int j=1;j<=n;j++) if (k!=i&&k!=j&&i!=j) if (g[i][k]+g[k][j]<g[i][j]) g[i][j]=g[i][k]+g[k][j]; for ( int i=1;i<=n;i++) { int sum=0; for ( int j=1;j<=f;j++) if (g[i][l[j]]!=inf) sum+=g[i][l[j]]; if (sum<mn) mn=sum,ans=i; } printf( "%d" ,ans); } |
P12331. Cow Contest奶牛的比赛
Description
FJ的N(1 <= N <= 100)头奶牛们最近参加了场程序设计竞赛:)。在赛场上,奶牛们按1..N依次编号。每头奶牛的编程能力不尽相同,并且没有哪两头奶牛的水平不相上下,也就是说,奶牛们的编程能力有明确的排名。
整个比赛被分成了若干轮,每一轮是两头指定编号的奶牛的对决。
如果编号为A的奶牛的编程能力强于编号为B的奶牛(1 <= A <= N; 1 <= B <= N; A != B) ,那么她们的对决中,编号为A的奶牛总是能胜出。
FJ想知道奶牛们编程能力的具体排名,于是他找来了奶牛们所有 M(1 <= M <= 4,500)轮比赛的结果,希望你能根据这些信息,推断出尽可能多的奶牛的编程能力排名。
比赛结果保证不会自相矛盾。
Format
Input
第1行: 2个用空格隔开的整数:N 和 M
第2..M+1行: 每行为2个用空格隔开的整数A、B,描述了参加某一轮比赛的奶 牛的编号,以及结果
(编号为A,即为每行的第一个数的奶牛为 胜者)
Output
第1行: 输出1个整数,表示排名可以确定的奶牛的数目
Samples
输入数据 1
5 5
4 3
4 2
3 2
1 2
2 5
输出数据 1
2
Hint
编号为2的奶牛输给了编号为1、3、4的奶牛,也就是说她的水平比这3头奶牛都差。
而编号为5的奶牛又输在了她的手下,也就是说,她的水平比编号为5的奶牛强一些。
于是,编号为2的奶牛的排名必然为第4,编号为5的奶牛的水平必然最差。其他3头奶牛的排名仍无法确定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include<bits/stdc++.h> using namespace std; int n,m,fr,ta,f[505][505],ans; int main() { cin>>n>>m; for ( int i=1,x,y;i<=m;i++) cin>>x>>y,f[x][y]=1; for ( int k=1;k<=n;k++) for ( int i=1;i<=n;i++) for ( int j=1;j<=n;j++) if (k!=i&&k!=j&&i!=j) if (f[i][k]&&f[k][j]) f[i][j]=1; for ( int i=1;i<=n;i++) { int sum=0; for ( int j=1;j<=n;j++) if (f[i][j]||f[j][i])sum++; if (sum==n-1)ans++; } cout<<ans; return 0; } |
P12332. 最短路上的统计
ID: 2079
传统题
1000ms
256MiB
尝试: 84
已通过: 26
难度: 6
上传者:
管理员 (root)
标签>
Description
一个无向图上,没有自环,所有边的权值均为1,对于一个点对(a,b) 我们要把所有a与b之间所有最短路上的点的总个数输出。
Format
Input
第一行n,m,表示n个点,m条边
接下来m行,每行两个数a,b,表示a,b之间有条边
在下来一个数p,表示问题的个数
接下来p行,每行两个数a,b,表示询问a,b
n<=100,p<=5000
Output
对于每个询问,输出一个数c,表示a,b之间最短路上点的总个数
Samples
输入数据 1
5 6
1 2
1 3
2 3
2 4
3 5
4 5
3
2 5
5 1
2 4
输出数据 1
4
3
2
Hint
对于第一个询问有2,3,4,5这四个点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include<bits/stdc++.h> using namespace std; int n,m,p,dis[1005][1005]; int x,y; int main() { cin>>n>>m; memset(dis,0x3f, sizeof (dis)); for ( int i=1;i<=m;i++) { cin>>x>>y; dis[x][y]=dis[y][x]=1; } for ( int i=1;i<=n;i++) dis[i][i]=0; for ( int k=1;k<=n;k++) for ( int x=1;x<=n;x++) for ( int y=1;y<=n;y++) dis[x][y]=min(dis[x][y],dis[x][k]+dis[k][y]); cin>>p; for ( int i=1;i<=p;i++) { int l,r,ans=0; cin>>l>>r; for ( int j=1;j<=n;j++) if (dis[l][j]+dis[r][j]==dis[l][r]) ans++; cout<<ans<<endl; } return 0; } |
P12364. 删边操作1
Description
给定一个N节点无向连通图,问最多可以删除多少条边,使得删除后的图,对于两个节点 U,V其最短路没有发生改变。
图中没有自环,没有重边
Format
Input
第一行给出N,M,分别代表点与边
接下来M行,描述这个图
N<=300
Output
如题
Samples
输入数据 1
3 3
1 2 2
2 3 3
1 3 6
输出数据 1
1
如上图,本来1与3之间有边为9
但却找到了中间点2,更新了1到3的最短路
于是1到3的边,是可以不要的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <bits/stdc++.h> using namespace std; int n, m, ans; int dis[305][305]; //最短路数组 struct edge { int u, v, w; } e[100005]; int main() { cin >> n >> m; memset(dis, 0x3f, sizeof (dis)); for ( int i = 1, u, v, w; i <= m; i++) { cin >> u >> v >> w; e[i].u = u, e[i].v = v, e[i].w = w; dis[u][v] = dis[v][u] = w; } for ( int i = 1; i <= n; i++) dis[i][i] = 0; for ( int k = 1; k <= n; k++) for ( int i = 1; i <= n; i++) for ( int j = 1; j <= n; j++) dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); //Floyd for ( int i = 1; i <= m; i++) //枚举所有的边 { int flag = 0; for ( int j = 1; j <= n; j++) //枚举中间点 { if (j != e[i].u && j != e[i].v) if (dis[e[i].u][e[i].v] == dis[e[i].u][j] + dis[j][e[i].v]) //对于e[i].u与e[i].v这两个点来说 //它们本是一条边上的两个点 //现在它们之间的最短路,居然找到了一个中间点来更新来最短路 //说明它们两者之间从前的边,是可以去掉的 flag = 1; } ans += flag; } cout << ans; return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2020-04-19 最小点覆盖=最大匹配证明
2020-04-19 趣味讲解匈牙利算法