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的更新方法,不是递加而是加上前面结点的值。

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

  • 相关阅读:
    更易型算法(Manipulating Algorithms)
    迭代器之配接器
    Windows下BBv2安装编译libtorrent
    swfupload简单使用
    Openx 中文编码解决方案
    常见c语言编译错误解析(转)
    新建一个scrapy项目
    判断两个日期的时间部分之差
    javascript弹出子窗口并返回值
    转:浅析ASP.NET中页面传值的几种方法
  • 原文地址:https://www.cnblogs.com/ChanWunsam/p/10018205.html
Copyright © 2011-2022 走看看