hdu 1102 Constructing Roads

There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.

We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.

Input

The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j.

Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.

Output

You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.

Sample Input

3
0 990 692
990 0 179
692 179 0
1
1 2

Sample Output

179

【题意】有n个村庄,现在让你修路让各个村庄相互连通,现在已经有些路联通了,现在告诉你在两个村庄间修路的代价,问你让所有村庄相互连通的最小花费。

【分析】最小生成树问题,还是比较简单,就是已知的路直接赋值为0就行。

【代码】

#include
#include 
#include 
#include 
#include 
using namespace std;
int len;
int dis[2005][2005];
bool vis[2005];
int mindis[2005];
int ans(void)
{
    vis[0]=true;
    for(int i=1; i0][i];
    int ret=0;
    for(int z=1; zint now=0;
        int minm=100000000;
        for(int i=0; iif(!vis[i]&&minm>mindis[i])
            {
                minm=mindis[i];
                now=i;
            }
        }
        if(now==0) return ret;
        vis[now]=true;
        ret+=mindis[now];
        for(int i=0; iif(!vis[i])
                mindis[i]=min(mindis[i],dis[i][now]);
        }
    }
    return ret;
}
int main()
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d",&len)!=EOF)
    {
        memset(vis,false,sizeof(vis));
        for(int i=0; ifor(int j=0; jscanf("%d",&dis[i][j]);
        int x;
        scanf("%d",&x);
        int from,to;
        while(x--)
        {
            scanf("%d%d",&from,&to);
            from--;//点是从1开始
            to--;
            dis[from][to]=dis[to][from]=0;//两条路都是0
        }
        printf("%d\n",ans());
    }
    return 0;
}

你可能感兴趣的:(hdu,最小生成树)