HDu 1879最小生成ツリーprimアルゴリズム実装

3996 ワード

http://acm.hdu.edu.cn/showproblem.php?pid=1879
この问题はとても奇妙で、G++で直接タイムアウトして、c++も400 ms过ぎます...
最小生成ツリーのprimアルゴリズムについてお話しします
私の理解によれば、その主な考え方は、任意に1つの点(通常は1つ目)を取り、1つのdis[i]で終点iの生成ツリー内の任意の点までの最小の距離を記憶し、生成ツリーに追加されたノードの外に1つの点を探し、この点から生成ツリーまでの距離が最小であれば(生成ツリーのどのノードまでも).このように最小の重みを見つけるまで、貪欲な思想であり、毎回最小であり、最小であることは間違いない.
hdu 1879 prim
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000
#define INF 100000000
int n;
int map[M][M];
int dis[M];
int used[M];
int sum;
void mst()
{
    for(int i = 1;i <= n;i++)
    {
        dis[i] = map[1][i];  //             1     
    }
    used[1] = 1;//  1       
    for(int i = 2;i <= n;i++)  //  n-1  
    {
        int min = INF;
        int j;
        for(int k = 1;k <= n;k++)
        {
            if(!used[k]&&dis[k]<min) //                 
            {
                min = dis[k];
                j = k;
            }
        }
        used[j] = 1;  //        
        //           if(min==INF)            ,            hdu1863     。
        sum += min;
        for(int k = 1;k <= n;k++)  
        {
            if(!used[k]&&map[j][k]<dis[k])  //  dis  (        )
                dis[k] = map[j][k];
        }
    }
}
int main()
{
    while(scanf("%d",&n)==1 && n)
    {
        sum = 0;
        memset(used,0,sizeof(used));
        //for(int i = 0;i < n;i++)
        //for(int j = 0;j < n;j++)         prim                     ,              INF
        //map[i][j] = INF;                   n*(n-1)/2                  ,      
        for(int i = 1;i <= n*(n-1)/2;i++)
        {
            int a,b,c,d;
            scanf("%d %d %d %d",&a,&b,&c,&d);
            if(d==1)
                map[a][b] = map[b][a] = 0;//            
            else
                map[a][b] = map[b][a] = c;
        }
        mst();
        printf("%d
",sum); } return 0; }

ここには他の人が書いたprimアルゴリズムを添付します.この問題には向いていませんが、注釈が詳しくて理解しやすいと思います.
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
#define MAXCOST 0x7fffffff

int graph[MAX][MAX];

int Prim(int graph[][MAX], int n)
{
	/* lowcost[i]   i          , lowcost[i]=0     i      */
	int lowcost[MAX];

	/* mst[i]    lowcost[i]   , mst[i]=0     i      */
	int mst[MAX];

	int i, j, min, minid, sum = 0;

	/*     1        , 2         */
	for (i = 2; i <= n; i++)
	{
		/*              1       */
		lowcost[i] = graph[1][i];

		/*               1    */
		mst[i] = 1;
	}

	/*   1         */
	mst[1] = 0;

	/* n       n-1          */
	for (i = 2; i <= n; i++)
	{
		min = MAXCOST;
		minid = 0;

		/*               minid */
		for (j = 2; j <= n; j++)
		{
			/*              */
			if (lowcost[j] < min && lowcost[j] != 0)
			{
				min = lowcost[j];
				minid = j;
			}
		}
		/*          :  ,  ,   */
		printf("%c - %c : %d
", mst[minid] + 'A' - 1, minid + 'A' - 1, min); /* */ sum += min; /* minid */ lowcost[minid] = 0; /* minid */ for (j = 2; j <= n; j++) { /* */ if (graph[minid][j] < lowcost[j]) { /* */ lowcost[j] = graph[minid][j]; /* */ mst[j] = minid; } } } /* */ return sum; } int main() { int i, j, k, m, n; int x, y, cost; char chx, chy; /* */ scanf("%d%d", &m, &n); getchar(); /* , */ for (i = 1; i <= m; i++) { for (j = 1; j <= m; j++) { graph[i][j] = MAXCOST; } } /* */ for (k = 0; k < n; k++) { scanf("%c %c %d", &chx, &chy, &cost); getchar(); i = chx - 'A' + 1; j = chy - 'A' + 1; graph[i][j] = cost; graph[j][i] = cost; } /* */ cost = Prim(graph, m); /* */ printf("Total:%d
", cost); }