专题四 Problem A

来源:互联网 发布:win10提速 优化 编辑:程序博客网 时间:2024/05/17 22:59
一、题目编号:
          1001
二、简单题意:
      有n座城市,每两座城市间可以修一些道路联系起来。城市A和城市B有道路或者它们之间可以通过其它城市的道路连接起来则称为A和B有联系。现在这些城市里已经有一些道路,要把所有的城市联系起来,求要修路的最小长度。
三、解题思路形成过程
        这个题可以用老师刚讲的并查集来做。有联系的道路组成一个集合,没有联系的道路集合组成不相交集合,把城市之间的距离排序,利用并查集的合并,即可得到最短的道路长度。
四、感想
       思路挺简单,代码实现起来也不是很难,注意好细节就没很大问题。但是我觉着我做对了,也实在找不出错了,还是一直WA.。最终百度了好久,最终终于发现应该是多组测试数据。题目里也没有说多组测试数据啊,晕死了。
五、AC代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX=102;
struct village
{
    int s,e,d;
};

bool map[MAX][MAX]={0};
int set[MAX];//并查集
village vil[21000];

int findx(int x)
{
    if(x!=set[x])
    set[x]=findx(set[x]);
    return set[x];
}

bool merge(int x,int y)
{
    int fx,fy;
    fx=findx(x);
    fy=findx(y);
    if(fx==fy)//属于同一分支
    return false;
    else
    {
    set[fx]=fy;
    return true;
    }
}

bool cmp(village a,village b)
{
    return a.d<b.d;
}

int main()
{
    int n;
    while(cin>>n&&n!=0)
    {

    int q,a,b,dist,result=0,num=0,k=0;
    for(int i=1;i<=n;++i)
    set[i]=i;

    memset(map, 0, sizeof(map));

    for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j)
    {
        cin>>dist;
        if(i<j)
        {
            vil[k].s=i;
            vil[k].e=j;
            vil[k].d=dist;
            k++;
        }
    }
    sort(vil,vil+k,cmp);
    cin>>q;
    while(q--)
    {
        cin>>a>>b;
        merge(a,b);
        map[a][b]=true;
    }
    for(int i=0;i<k;i++)
    {
        int x=vil[i].s;
        int y=vil[i].e;
        if(map[x][y])
        continue;
        if(merge(x,y))
        result+=vil[i].d;
    }

    cout<<result<<endl;
    }
    return 0;

}
0 0
原创粉丝点击