两道floyd的简单题目。最近才学,写起来有点生硬。
POJ1125先算出最短路径然后找最佳人选和最短时间。
#include<cstdio>
const int inf=20;
int n,dis[101][101];
void floyd()
{
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i!=j&&dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
int maxlen,min=inf,flag;
for(i=1;i<=n;i++)
{
maxlen=0;
for(j=1;j<=n;j++)
if(i!=j&&maxlen<dis[i][j])
maxlen=dis[i][j];
if(min>maxlen)
{
min=maxlen;
flag=i;
}
}
if(min<inf)
printf("%d %d\n",flag,min);
else
printf("disjoint\n");
return;
}
int main()
{
int i,j;
while(scanf("%d",&n)&&n)
{
for(i=1;i<=101;i++)
for(j=1;j<=101;j++)
dis[i][j]=20;
for(i=1;i<=n;i++)
{
int k;
scanf("%d",&k);
for(j=1;j<=k;j++)
{
int p,d;
scanf("%d%d",&p,&d);
dis[i][p]=d;
}
}
floyd();
}
}
之后是用floyd求最小环。这题不要求过所有的景点。。一开始不审题想多了。。。
主要利用到的原理是当处理到k时,所有以1 到k - 1为中间结点的最短路径都已经确定,则这时候的环为(i到j(1 < i, j <= k - 1)的最短路径) + 边(i, k) + 边(k, j)遍历所有的i, j找到上述式子的最小值即位k下的最小代价环(这原理摘自http://blog.youkuaiyun.com/youngyangyang04/article/details/7054931,学习了)
#include<cstdio>
#include<string.h>
#define ll long long
const ll INF=1<<15;
ll ans;
int dis[101][101],m[101][101];
void floyd(int n)
{
int i,j,k;
ans=INF;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
m[i][j]=dis[i][j];
for(k=1;k<=n;k++)
{
for(i=1;i<k;i++)
for(j=i+1;j<k;j++)
ans=dis[i][j]+m[i][k]+m[k][j]<ans?dis[i][j]+m[i][k]+m[k][j]:ans;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
dis[i][j]=(dis[i][k]+dis[k][j]<dis[i][j])?dis[i][k]+dis[k][j]:dis[i][j];
}
if(ans==INF)
printf("No solution.\n");
else
printf("%lld\n",ans);
}
int main()
{
int i,j,k,n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(dis,0,sizeof(dis));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
dis[i][j]=INF;
for(i=1;i<=m;i++)
{
int p,q,d;
scanf("%d%d%d",&p,&q,&d);
dis[p][q]=dis[q][p]=d;
}
floyd(n);
}
}