zoj2048

来源:互联网 发布:国外域名后缀 编辑:程序博客网 时间:2024/06/03 16:12

题目大意:

Flatopia需要建更多公路,使得开车不离开公路可以到任何两个镇。Flatopian镇从1到N编号并且有坐标。每条公路连接两个镇,所有的公路都是直的。所有的公路都是双向的。公路可以相互交,司机只可以在公路的末端交换。
Flatopian政府想要最小化成本。然而,他们想保证任何两个镇 都是可以到达的。
输入:N,第一行镇子的数量,接下来的N行包括坐标。
接下来的一行M,代表现存铁路的数量,接下来的M行包括 铁路路线

解题思路:

最小生成树问题

代码入下:

#include <stdio.h>#include <string.h>#include <stdlib.h>#define MAX 755typedef struct{    int x, y;    int w;}edge;edge e[MAX*MAX/2];int rank[MAX], father[MAX];int cmp(const void *a, const void *b){    if ((*(edge *)a).w > (*(edge *)b).w)    return 1;    return -1;}void Make_Set(int x){    father[x] = x;    rank[x] = 0;}int Find_Set(int x){    if (x != father[x])       father[x] = Find_Set(father[x]);    return father[x];}void Link(int x, int y, int w){    if (rank[x] > rank[y])  father[y] = x;    else    {        father[x] = y;        if (rank[x] == rank[y])  rank[y]++;    }}void Kruskal(int point_amou, int edge_amou){    int i, x, y;    qsort(e, edge_amou, sizeof(edge), cmp);    for (i = 0; i < edge_amou; i++)    {        x = Find_Set(e[i].x);        y = Find_Set(e[i].y);        if (x != y)       {        Link(x, y, e[i].w);        printf("%d %d\n", e[i].x+1, e[i].y+1);     }    }}    int main(void){    int T, N, M, i, j, cnt, s, t;    int a[755], b[755];    scanf("%d", &T);    while(T--)    {     scanf("%d", &N);     for(i = 0; i < N; i++)     {        scanf("%d %d", &a[i], &b[i]);        Make_Set(i);     }     cnt = 0;     for(i = 0; i < N; i++)     {        for(j = i+1; j < N; j++)        {         e[cnt].x = i;         e[cnt].y = j;         e[cnt].w = (a[i]-a[j])*(a[i]-a[j]) + (b[i]-b[j])*(b[i]-b[j]);         cnt++;        }     }     scanf("%d", &M);     for(i = 0; i < M; i++)     {        scanf("%d %d", &s, &t);        s--;        t--;        s = Find_Set(s);        t = Find_Set(t);        Link(s, t, 0);     }     Kruskal(N, cnt);     if(T) printf("\n");    }    return 0;}
0 0
原创粉丝点击