A - Til the Cows Come Home
题意:t条边,n个点,求最短路。2<=n<=1000,1<=t<=2000。
题解:floyd时间复杂度O(n^3)1e9肯定超时.
//Floyd,超时代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
const int maxn=2010;
ll mp[maxn][maxn];
int main(){
int t,n;
scanf("%d%d",&t,&n);
int u,v;
ll w;
memset(mp,INF,sizeof(mp));
for(int i=0;i<t;i++){
scanf("%d%d%lld",&u,&v,&w);
mp[u][v]=w;
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
}
}
}
printf("%lld\n",mp[1][n]);
return 0;
}
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
const int maxn=2010;
ll mp[maxn][maxn],dist[maxn],vis[maxn];
int t,n;
void Dijkstra(){
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
dist[i]=mp[1][i];
}
dist[1]=0;
vis[1]=1;
ll tmp;
int k;
for(int i=1;i<n;i++){
tmp=INF;
for(int j=1;j<=n;j++){
if(!vis[j]&&tmp>dist[j]){
tmp=dist[j];
k=j;
}
}
if(tmp==INF) return ;
vis[k]=1;
for(int j=1;j<=n;j++){
if(!vis[j]&&dist[j]>dist[k]+mp[k][j]) dist[j]=dist[k]+mp[k][j];
}
}
}
int main(){
scanf("%d%d",&t,&n);
int u,v;
ll w;
memset(mp,INF,sizeof(mp));
for(int i=0;i<t;i++){
scanf("%d%d%lld",&u,&v,&w);
if(w<mp[u][v]){ //可能有多条边
mp[u][v]=w;
mp[v][u]=w;
}
}
Dijkstra();
printf("%lld\n",dist[n]);
return 0;
}
B - Frogger
题意:青蛙从第一个石头到第二个石头,保证他能够跳到第二个石头,那么他最小的跳跃距离是多少?
题解:从第一个石头到第二个石头有多条路线,求所有条路线中每两个石头间距离的最大值最小化。
代码1:Floyd
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn=210;
double x[maxn],y[maxn];
double mp[maxn][maxn]; //mp[i][j]表示从i到j的经过的所有路线中的最大值
int n;
void Floyd(){
for(int k=0;k<n;k++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
mp[i][j]=min(mp[i][j],max(mp[i][k],mp[k][j])); //经过k点,使得石头i到石头j的最大跳跃距离减小
}
}
}
}
int main(){
int cnt=0;
while(~scanf("%d",&n)){
if(n==0) break;
for(int i=0;i<n;i++){
scanf("%lf%lf",&x[i],&y[i]);
}
memset(mp,INF,sizeof(mp));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
mp[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
}
Floyd();
printf("Scenario #%d\nFrog Distance = %.3f\n\n",++cnt,mp[0][1]);
}
return 0;
}
代码2:Dijkstra
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn=210;
double x[maxn],y[maxn];
double mp[maxn][maxn],dist[maxn];
int vis[maxn];
int n;
void Dijkstra(){
for(int i=0;i<n;i++){
dist[i]=mp[0][i];
vis[i]=0;
}
vis[0]=1;
for(int i=1;i<n;i++){
int k;
double tmp=INF*1.0;
for(int j=0;j<n;j++){
if(!vis[j]&&tmp>dist[j]){
tmp=dist[j];
k=j;
}
}
if(tmp==INF*1.0) break;
vis[k]=1;
for(int j=0;j<n;j++){
if(!vis[j])
dist[j]=min(dist[j],max(dist[k],mp[k][j]));
}
}
}
int main(){
int cnt=0;
while(~scanf("%d",&n)){
if(n==0) break;
for(int i=0;i<n;i++){
scanf("%lf%lf",&x[i],&y[i]);
}
memset(mp,INF,sizeof(mp));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
mp[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
}
Dijkstra();
printf("Scenario #%d\nFrog Distance = %.3f\n\n",++cnt,dist[1]);
}
return 0;
}