http://acm.hdu.edu.cn/showproblem.php?pid=3631
题意:给一个图。接着是M个操作,有两种:1.标记某个点2.求某两点间的最短路径,要求该路径通过被标记的点。
利用弗洛伊德算法思想,每次新标记一个点时,判断以下该点是否会对其他两点间的距离造成影响。
#include<cstdio>
#include<iostream>
using namespace std;
#define M 2000000
#define N 1005
int a[N][N],aa[N],n,m,q;
bool tp[N];
void init()
{
int i,j,b,c,h;
for (i=0;i<=n;i++)
for (j=0;j<=n;j++)
if (i==j) a[i][j]=0;//这里不能也是M
else a[i][j]=M;
for (i=1;i<=m;i++)
{
scanf("%d%d%d",&b,&c,&h);
if (h<a[b][c]) a[b][c]=h;
}
for (i=0;i<=n;i++) tp[i]=false;
}
int main()
{
//freopen("a","r",stdin);
int i,j,t,kk=0;
scanf("%d%d%d",&n,&m,&q);
while (1)
{
if (n==0 && m==0 && q==0) break;
kk++;
printf("Case %d:\n",kk);
init();
int x,y,z;
for (t=1;t<=q;t++)
{
scanf("%d%d",&z,&x);
if (z==0)
{
if (tp[x]==true)
{
printf("ERROR! At point %d\n",x);
continue;
}
tp[x]=true;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (i!=x && j!=x && a[i][x]!=M && a[x][j]!=M)
{
if (a[i][x]+a[x][j]<a[i][j])
a[i][j]=a[i][x]+a[x][j];
}
}
else if (z==1)
{
scanf("%d",&y);
if (tp[x]==false || tp[y]==false)
{
printf("ERROR! At path %d to %d\n",x,y);
continue;
}
if (a[x][y]==M)
{
printf("No such path\n");
continue;
}
printf("%d\n",a[x][y]);
}
}
scanf("%d%d%d",&n,&m,&q);
if (n!=0 || m!=0 || q!=0)printf("\n");
}
return 0;
}