llk657843 2015-05-05 12:54 采纳率: 0%
浏览 1667

ACM HDU1879继续畅通工程 提交RE.求各路大神帮忙看一下哪儿错了

题目大意:
求最小生成树的权值和,并输出。已经修建的路(已经连上的边)是不会算入到最后的ANS中。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。

当N为0时输入结束。

Sample Input

3
1 2 1 0
1 3 2 0
2 3 4 0
3
1 2 1 0
1 3 2 0
2 3 4 1
3
1 2 1 0
1 3 2 1
2 3 4 1
0

Sample Output

3
1
0

我的思路:就是把创建部分稍微做点修改,改成如果修建过,则此边的权值为0。
我出现的问题:我是初学PRIM,算法是自己根据定义写的,可能比较毛糙,问题不知道出在哪儿。提交上去是RE,(ACCESS_VIOLATION)。我仔细看过数组是否越界,我并没有看出有越界的地方。
上一道HDU1863畅通工程,同类型的题目我用这个算法AC了。
所以现在不知道错误在哪儿,请求各位指点一二。

下面是我的代码,运行没有问题,样例也通过。。。
#include "iostream"
#include "algorithm"
using namespace std;
typedef struct
{
int from;
int to;
int value; //权值
bool used; //是否被标记过
bool now; //是否为待选直接相邻边
}Edge;
Edge e[105];
bool V[105];//顶点集。
const int Inf=10000000;
bool Mycmp(Edge A,Edge B)
{
return A.value<B.value;
}

void Create(int n)
{
int i,length=0,Q;

for(i=0;i V[i]=false;
for(i=0;i e[i].used=false;
for(i=0;i {
cin>>e[i].from>>e[i].to>>e[i].value>>Q;
if(Q==1)
e[i].value=0;
}
stable_sort(e,e+n,Mycmp);

}
void Find(int n,int from) //用来找出和这个顶点直接相连的边。
{
int i;
for(i=0;i<n;i++)
{
if(e[i].used==false&&(e[i].from==from||e[i].to==from))

{
if(V[e[i].from]==true&&V[e[i].to]==true) //用于判断是否会构成环
continue;
e[i].now=true;
}
}

}
void Clear(int n)
{
for(int i=0;i<n;i++)
e[i].now=false;

}

int Prim(int n,int m)
{
int i,from,to,j,jindex,value,min,ans=0;
from=e[0].from;

to=e[0].to;
e[0].used=true;
V[from]=true;

V[to]=true;
ans+=e[0].value;
for(i=1;i {
Clear(n);
for(j=1;j {
if(V[j]==true) //顺着顶点,把边挑选出来
{
Find(n,j);
}
}
min=Inf;
jindex=-1;
for(j=0;j {
if(e[j].now==true)
{
if(min>e[j].now)
{
min=e[j].now;
jindex=j;
}
}
}

    e[jindex].used=true;    //找到合适的边
    V[e[jindex].from]=true;
    V[e[jindex].to]=true;
    ans+=e[jindex].value;

}
return ans;

}

int main()
{
int n,m,ans,t,flag;
while(cin>>m)
{

    if(m==0)    //题意,如果为0则跳出
        break;
    n=m*(m-1)/2;
  Create(n);
 ans=Prim(n,m);
    cout<<ans<<endl; 
}
return 0;

}

  • 写回答

1条回答 默认 最新

  • lx624909677 2015-05-07 05:22
    关注

    算法有问题

     /*
    hdu1879
    2013-03-18 15:25:50    Accepted    1879    406MS    360K    1188 B    
    典型的最小生成树,在做并查集时做的这道题,
    所以使用并查集实现的克鲁斯卡尔算法
    */
    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    
    struct node {
        int start ,end,expense,flag;
    }data[5005];
    
    int father[105];
    void make_set(int n)
    {
        for(int i=1;i<=n;i++)
            father[i]=i;
    }
    int find_set(int x)
    {
        if(x^father[x])
            father[x]=find_set(father[x]);
        return father[x];
    }
    int union_set(int x,int y)
    {
        x=find_set(x);
        y=find_set(y);
        if(x==y)
            return 0;
        father[x]=y;
        return 1;
    }
    bool cmp(node a,node b)
    {
        return a.expense<b.expense;
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            if(!n)
                break;
            make_set(n);
            int ans=0;
            int m=(n-1)*n/2;
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d%d",&data[i].start,&data[i].end,&data[i].expense,&data[i].flag);
                if(data[i].flag)//当道路修通时,规定一节点为另一节点的父亲
                    father[data[i].start]=data[i].end;
            }
            sort(data,data+m,cmp);//按道路的花费升序排列
    
            //在不构成环的前提下,选择最短的边,有贪心的思想
            for(int i=0;i<m;i++)
            {
                if(union_set(data[i].start,data[i].end))
                    ans+=data[i].expense;
            }
            printf("%d\n",ans);
        }
        return 0;
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!