zoukankan      html  css  js  c++  java
  • 1003. Emergency


    这道题一开始就卡在了题目没看清这个问题上。题目是最短路径的变形,但是输出要求的最短路径的条数和路径上结点值的最大和。

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MaxVertexNum 500
    #define INFINITY 65535					/* 二进制的2^16,即int类型最大储存值 */
    
    typedef int ElementType;
    typedef int WeightType;
    typedef int Vertex;
    
    
    /* 图结点 */
    struct GNode{
    	int Nv, Ne;
    	WeightType G[MaxVertexNum][MaxVertexNum];
    	ElementType Data[MaxVertexNum];
    };
    typedef struct GNode *PtrToGNode;
    typedef PtrToGNode MGraph;
    
    
    MGraph CreateGraph(int VertexNum);
    MGraph BuildGraph(int M, int N);
    void Dijkstra_X(MGraph Graph, int path[], int dist[], Vertex S, Vertex E);
    Vertex FindMindist(MGraph Graph, int dist[], int collected[]);
    
    
    int main()
    {
        //freopen("C:\Users\ChanWunsam\Desktop\pat\pat_in.txt","r",stdin);
        //freopen("C:\Users\ChanWunsam\Desktop\pat\pat_out.txt","w",stdout);
    
    	int M, N, C1, C2;
    	int dist[MaxVertexNum], path[MaxVertexNum], Sum;
    	MGraph Graph;
    	Vertex W;
    
    	scanf("%d %d %d %d", &M, &N, &C1, &C2);
    	Graph=BuildGraph(M, N);
    	if(C1==C2)                                  /* 如果起始地和目的地相同 */
        {
            printf("%d %d", 1, Graph->Data[C1]);
        }
        else
            Dijkstra_X(Graph, dist, path, C1, C2);
    
    	return 0;
    }
    
    
    MGraph CreateGraph(int VertexNum)
    {
    	Vertex V, W;
    	MGraph Graph;
    
    	Graph=(MGraph)malloc(sizeof(struct GNode));
    	Graph->Nv=VertexNum;
    	Graph->Ne=0;
    	for(V=0; V<VertexNum; V++)
    	{
    		Graph->Data[V]=-1;
    		for(W=0; W<VertexNum; W++)
    		{
    			Graph->G[V][W]=INFINITY;
    		}
    	}
    
    	return Graph;
    }
    
    MGraph BuildGraph(int M, int N)
    {
    	int data, i;
    	Vertex V, W;
    	WeightType Weight;
    	MGraph Graph;
    
    	Graph=CreateGraph(M);
    	Graph->Ne=N;
    
    	for(V=0; V<Graph->Nv; V++)
    	{
    		scanf("%d", &data);
    		Graph->Data[V]=data;
    	}
    	for(i=0; i<Graph->Ne; i++)
    	{
    		scanf("%d %d %d", &V, &W, &Weight);
    		/* 插入边 */
    		Graph->G[V][W]=Weight;
    		Graph->G[W][V]=Weight;
    	}
    
    	return Graph;
    }
    
    void Dijkstra_X(MGraph Graph, int path[], int dist[], Vertex S, Vertex E)	/* 单源最短路径算法变形 */
    {
        /* path记录每个点的最短路径条数,dist记录每个点的最短路径长度,Sum记录每个点的最短路径上的最大救援队数量 */
        int collected[MaxVertexNum], Sum[MaxVertexNum];
        Vertex V, W;
    
        /* 初始化:此处默认邻接矩阵中不存在的边用INFINITY表示 */
        dist[S] = 0;
        collected[S] = true;
        Sum[S]=Graph->Data[S];
    
        for ( V=0; V<Graph->Nv; V++ )
        {
            if(V==S)
                V++;
    
            dist[V] = Graph->G[S][V];
            if ( dist[V]<INFINITY )
            {
                Sum[V]=Sum[S]+Graph->Data[V];
                path[V] = 1;
            }
            else                                    /* 如果没有路径,赋值-1,方便检查 */
            {
                Sum[V]=-1;
                path[V] = -1;
            }
            collected[V] = false;
        }
    
    
        while (1) {
            /* V = 未被收录顶点中dist最小者 */
            V = FindMindist( Graph, dist, collected );
            if ( V==-1 ) /* 若这样的V不存在 */
                break;      /* 算法结束 */
            collected[V] = true;  /* 收录V */
            for( W=0; W<Graph->Nv; W++ ) /* 对图中的每个顶点W */
                /* 若W是V的邻接点并且未被收录 */
                if ( collected[W]==false && Graph->G[V][W]<INFINITY ) {
                    /* 若收录V使得dist[W]变小 */
                    if ( dist[V]+Graph->G[V][W] < dist[W] ) {
                        dist[W] = dist[V]+Graph->G[V][W];            /* 更新dist[W] */
                        path[W] = path[V];
                        Sum[W]=Sum[V]+Graph->Data[W];
                    }
                    else if(dist[V]+Graph->G[V][W] == dist[W]){
                        path[W]+=path[V];
                        if(Sum[V]+Graph->Data[W] > Sum[W])
                            Sum[W]=Sum[V]+Graph->Data[W];
                    }
                }
        } /* while结束*/
    
    	printf("%d %d", path[E], Sum[E]);
    }
    
    Vertex FindMindist(MGraph Graph, int dist[], int collected[])
    {
    	Vertex V, MinV;
    	int MinDist;
    
    	MinDist=INFINITY;
    	for(V=0; V<Graph->Nv; V++)
    	{
    		if(!collected[V] && dist[V]<MinDist)
    		{
    			MinDist=dist[V];
    			MinV=V;
    		}
    	}
    
    	if(MinDist<INFINITY)
    		return MinV;
    	else
    		return -1;
    }
    
    

    实在做太久了,这周的任务铁定完不成。

    最后是卡在了第二个测试点,这个测试点是起始点和目的点相同,输出会比较特殊。

    需要注意的是path和Sum的更新方法,不是递加而是加上前面结点的值。

    我的代码可能看起来比较方便,但是时间复杂度和空间复杂度就没那么好了,就这样吧。

  • 相关阅读:
    SSL JudgeOnline 1194——最佳乘车
    SSL JudgeOnline 1457——翻币问题
    SSL JudgeOnlie 2324——细胞问题
    SSL JudgeOnline 1456——骑士旅行
    SSL JudgeOnline 1455——电子老鼠闯迷宫
    SSL JudgeOnline 2253——新型计算器
    SSL JudgeOnline 1198——求逆序对数
    SSL JudgeOnline 1099——USACO 1.4 母亲的牛奶
    SSL JudgeOnline 1668——小车载人问题
    SSL JudgeOnline 1089——USACO 1.2 方块转换
  • 原文地址:https://www.cnblogs.com/ChanWunsam/p/10018205.html
Copyright © 2011-2022 走看看