http://blog.acmj1991.com/?p=679
题意:给定一个有向图,给定两个操作 0 x 表示x点被标记已经能走。
1 x y x点到y点的最短距离(只能走被标记的点)
思路:开始的时候是想用dij但是悲剧了,其实很明显100000次的运算肯定会超时。后来发现其实就是一个加点求最短路的问题跟floyd差不多,只不过是将外层循环换到每次标记新的点是来执行
#include<stdio.h>
#include<string.h>
#define maxN 310
#define MAX 0x0fffffff
int map[maxN][maxN],vist[maxN];
int min(int x,int y){return x<y?x:y;}
void floyd(int u,int n)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(map[i][u]<MAX&&map[u][j]<MAX&&map[i][j]>map[i][u]+map[u][j])
map[i][j]=map[i][u]+map[u][j];
}
int main()
{
int n,m,q,u,v,w,l=1;
while(scanf("%d%d%d",&n,&m,&q)&&(n||m||q))
{
if(l>1)printf("\n");
printf("Case %d:\n",l++);
memset(vist,0,sizeof(vist));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i==j)map[i][j]=0;
else map[i][j]=MAX;
while(m--){
scanf("%d%d%d",&u,&v,&w);
map[u][v]=min(map[u][v],w);
}
while(q--){
scanf("%d",&w);
if(w){
scanf("%d%d",&u,&v);
if(!vist[u]||!vist[v])printf("ERROR! At path %d to %d\n",u,v);
else if(map[u][v]==MAX)printf("No such path\n");
else printf("%d\n",map[u][v]);
}else{
scanf("%d",&u);
if(vist[u])printf("ERROR! At point %d\n",u);
else{
vist[u]=1;
floyd(u,n);
}
}
}
}
}