http://acm.hdu.edu.cn/showproblem.php?pid=3631

只能走标记过的点,方法是标记哪个点就对哪个点做floyd

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
const int INF=0xfffffff ;
int n,m,q ;
int dis[305][305],vis[305] ;
void floyd(int k)
{
    for(int i=0 ;i<n ;i++)
    {
        for(int j=0 ;j<n ;j++)
        {
            if(i==j || i==k || k==j)continue ;
            dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]) ;
        }
    }
}
int main()
{
    int cas=1 ;
    int first=1 ;
    while(~scanf("%d%d%d",&n,&m,&q))
    {
        if(!n && !m && !q)break ;
        if(first)first=0 ;
        else putchar('\n') ;
        printf("Case %d:\n",cas++) ;
        for(int i=0 ;i<n ;i++)
        {
            for(int j=0 ;j<n ;j++)
            {
                if(i==j)dis[i][j]=0 ;
                else dis[i][j]=dis[j][i]=INF ;
            }
        }
        for(int i=0 ;i<m ;i++)
        {
            int s,t,v ;
            scanf("%d%d%d",&s,&t,&v) ;
            dis[s][t]=min(dis[s][t],v) ;
        }
        memset(vis,0,sizeof(vis)) ;
        for(int i=0 ;i<n ;i++)
            dis[i][i]=0 ;
        while(q--)
        {
            int op ;
            scanf("%d",&op) ;
            if(op)
            {
                int x,y ;
                scanf("%d%d",&x,&y) ;
                //printf("!!!%d %d %d\n",dis[x][y],vis[x],vis[y]) ;
                if(!vis[x] || !vis[y])
                {
                    printf("ERROR! At path %d to %d\n",x,y) ;
                }
                else if(dis[x][y]==INF)
                    puts("No such path") ;
                else{
                    printf("%d\n",dis[x][y]) ;
                }
            }
            else{
                int x ;
                scanf("%d",&x) ;
                if(vis[x])
                    printf("ERROR! At point %d\n",x) ;
                else
                {
                    vis[x]=1 ;
                    floyd(x) ;
                }
            }
        }
    }
    return 0 ;
}
View Code