hdu 3371最小生成ツリーprim

2623 ワード

http://acm.hdu.edu.cn/showproblem.php?pid=3371
いくつかの都市があることを教えて、更にどの2つの都市の间に道路を建てていくらを要して、あなたにどのいくつの都市の间にすでに道があって、再建する必要はありません.すべての都市間を連通させるのに最小いくらかかるかが要求されています.
ここではprimアルゴリズムを使いました.の都市間の権限値を保存し、すでに構築されている都市に対して、彼らの権限値を0に割り当てます.また,最小生成ツリーが見つかるかどうかを判断し,できなければ−1を出力し,点を巡ったときに最小のエッジが見つからなければ,最小生成ツリーがないに違いない.(各kaseの開始時にすべてのエッジをINFに初期化することに注意).
何度もWAに貢献しています...頭が悪いので、kaseごとにwhileを打って、ずっと退けませんでした.
コード:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define M 1009
#define INF 0x3f3f3f3f
int dis[M];
int map[M][M];
bool vis[M];
int n;
int ans;
int city[M];
bool prim()
{
    for(int i = 1;i <= n;i++)
        dis[i] = map[1][i];
    vis[1] = true;
    for(int i = 2;i <= n;i++)
    {
        int min = INF;
        int k;
        for(int j = 1;j <= n;j++)
        {
            if(!vis[j] && dis[j]<min)
            {
                min = dis[j];
                k = j;
            }
        }
        if(min==INF) return false; //            ,                
        ans += min;
        vis[k] = true;
        for(int j = 1;j <= n;j++)
        {
            if(!vis[j] && dis[j]>map[k][j])
            {
                dis[j] = map[k][j];
            }
        }
    }
    return true;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ans = 0;
        memset(vis,0,sizeof(vis));
        memset(city,0,sizeof(city));
        int m,k;
        scanf("%d%d%d",&n,&m,&k);   //     while(scanf(...))       WA     
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= n;j++)
        {
            map[i][j] = INF;
            map[j][i] = INF;
        }
        for(int i = 1;i <= m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            if(map[a][b]>c)
            map[a][b] = map[b][a] = c;
        }
        for(int i = 1;i <= k;i++)
        {
            int temp;
            scanf("%d",&temp);
            for(int i = 1;i <= temp;i++)
                scanf("%d",&city[i]);//         
            for(int i = 1;i <= temp;i++)
            for(int j = i+1;j <= temp;j++)
            {
                int a = city[i],b = city[j];
                map[a][b] = 0;
                map[b][a] = 0;
            }
        }
        bool ok = prim();
        if(!ok)
            printf("-1
"); else printf("%d
",ans); } return 0; }