HDU 3371 Connect the Cities(Prim,Kruskal)

来源:互联网 发布:淘宝账号严重违规冻结 编辑:程序博客网 时间:2024/06/05 15:49

题目地址:点击打开链接

题意:给你一堆城市,然后来了一次海啸,海啸完了还有一些城市是连在一块的,问把所有的城市连在最小的花费是多少

思路:Kruskal算法超了无数发,后来改用prim算法,把海啸过后,连在一块的城市之间的距离设为0即可,用C++提交

AC代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;const int maxn = 510;const int zui = 0x3f3f3f3f;int lowdist[maxn];int map1[maxn][maxn];int visit[maxn];int n,m,k,sum;bool flag;void Prim(){    int i,j,k;    memset(visit,0,sizeof(visit));    for(i=1; i<=n; i++)    {        lowdist[i] = map1[1][i];    }    visit[1] = 1;    sum = 0;    for(i=1; i<n; i++)    {        int min1 = zui;        for(j=1; j<=n; j++)        {            if(!visit[j] && lowdist[j] < min1)            {                min1 = lowdist[j];                k = j;            }        }        if(min1 == zui)        {            flag = false;            return;        }        visit[k] = 1;        sum += lowdist[k];        for(j=1; j<=n; j++)        {            if(!visit[j] && map1[k][j] < lowdist[j])            {                lowdist[j] = map1[k][j];            }        }    }}int main(){    int t;    int i,j;    scanf("%d",&t);    while(t--)    {        flag = true;        memset(map1,zui,sizeof(map1));        scanf("%d%d%d",&n,&m,&k);        int p,q,c;        for(i=1; i<=m; i++)        {            scanf("%d%d%d",&p,&q,&c);            if(c < map1[p][q])            {                map1[p][q] = map1[q][p] = c;            }        }        int l,temp,x;        for(i=1; i<=k; i++)        {            scanf("%d%d",&l,&temp);            for(j=1; j<l; j++)            {                scanf("%d",&x);                map1[temp][x] = map1[x][temp] = 0;            }        }        Prim();        if(flag)        {            printf("%d\n",sum);        }        else        {            printf("-1\n");        }    }    return 0;}

AC代码2:该开始用G++投的T了,和代码1没啥区别就是初始化是用了循环语句,后来代码1用从C++过了,然后把这个代码也试着用C++投,也过了,不过时间比代码1长一点

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;const int maxn = 510;const int zui = 1000000000;int lowdist[maxn];int map1[maxn][maxn];int visit[maxn];int n,m,k,sum;bool flag;void Prim(){    int i,j,k;    memset(visit,0,sizeof(visit));    for(i=1; i<=n; i++)    {        lowdist[i] = map1[1][i];    }    visit[1] = 1;    sum = 0;    for(i=1; i<n; i++)    {        int min1 = zui;        for(j=1; j<=n; j++)        {            if(!visit[j] && lowdist[j] < min1)            {                min1 = lowdist[j];                k = j;            }        }        if(min1 == zui)        {            flag = false;            return;        }        visit[k] = 1;        sum += lowdist[k];        for(j=1; j<=n; j++)        {            if(!visit[j] && map1[k][j] < lowdist[j])            {                lowdist[j] = map1[k][j];            }        }    }}int main(){    int t;    int i,j;    scanf("%d",&t);    while(t--)    {        flag = true;        scanf("%d%d%d",&n,&m,&k);        for(i=1; i<=n; i++)        {            for(j=1; j<=n; j++)            {                map1[i][j] = zui;            }            map1[i][i] = 0;        }        int p,q,c;        for(i=1; i<=m; i++)        {            scanf("%d%d%d",&p,&q,&c);            if(c < map1[p][q])            {                map1[p][q] = map1[q][p] = c;            }        }        int l,temp,x;        for(i=1; i<=k; i++)        {            scanf("%d%d",&l,&temp);            for(j=1; j<l; j++)            {                scanf("%d",&x);                map1[temp][x] = map1[x][temp] = 0;            }        }        Prim();        if(flag)        {            printf("%d\n",sum);        }        else        {            printf("-1\n");        }    }    return 0;}
最后来点Kruskal的超时代码

超时代码1:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;const int maxn = 510;const int zui = 1000000000;int lowdist[maxn];int map1[maxn][maxn];int visit[maxn];int n,m,k,sum;bool flag;void Prim(){    int i,j,k;    memset(visit,0,sizeof(visit));    for(i=1; i<=n; i++)    {        lowdist[i] = map1[1][i];    }    visit[1] = 1;    sum = 0;    for(i=1; i<n; i++)    {        int min1 = zui;        for(j=1; j<=n; j++)        {            if(!visit[j] && lowdist[j] < min1)            {                min1 = lowdist[j];                k = j;            }        }        if(min1 == zui)        {            flag = false;            return;        }        visit[k] = 1;        sum += lowdist[k];        for(j=1; j<=n; j++)        {            if(!visit[j] && map1[k][j] < lowdist[j])            {                lowdist[j] = map1[k][j];            }        }    }}int main(){    int t;    int i,j;    scanf("%d",&t);    while(t--)    {        flag = true;        scanf("%d%d%d",&n,&m,&k);        for(i=1; i<=n; i++)        {            for(j=1; j<=n; j++)            {                map1[i][j] = zui;            }            map1[i][i] = 0;        }        int p,q,c;        for(i=1; i<=m; i++)        {            scanf("%d%d%d",&p,&q,&c);            if(c < map1[p][q])            {                map1[p][q] = map1[q][p] = c;            }        }        int l,temp,x;        for(i=1; i<=k; i++)        {            scanf("%d%d",&l,&temp);            for(j=1; j<l; j++)            {                scanf("%d",&x);                map1[temp][x] = map1[x][temp] = 0;            }        }        Prim();        if(flag)        {            printf("%d\n",sum);        }        else        {            printf("-1\n");        }    }    return 0;}

k判环超时,改用n判环,里面少一个for循环,时间应该少很多

超时代码2:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;int pre[510];struct node{    int left,right,value;}a[25010];int cmp(const void *_a,const void *_b){    struct node *a = (node*)_a;    struct node *b = (node*)_b;    return a->value - b->value;}int findroot(int x){    return x == pre[x] ? x : pre[x] = findroot(pre[x]);//求根节点加路径压缩}int main(){    int t,n,m,k;    int i,j;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&m,&k);        for(i=1; i<=n; i++)        {            pre[i] = i;        }        for(i=0; i<m; i++)        {            scanf("%d%d%d",&a[i].left,&a[i].right,&a[i].value);        }        qsort(a,m,sizeof(node),cmp);        int sum,l,x;        int root1,root2;        for(i=0; i<k; i++)        {            scanf("%d",&sum);            scanf("%d",&l);            root1 = findroot(l);            for(j=1; j<sum; j++)            {                scanf("%d",&x);                root2 = findroot(x);                if(root1 != root2)                {                    pre[root2] = pre[root1];                    n--;                }            }        }        sum = 0;        for(i=0; i<m; i++)        {            root1 = findroot(a[i].left);            root2 = findroot(a[i].right);            if(root1 != root2)            {                sum += a[i].value;                pre[root1] = root2;                n--;            }            if(n == 1)                break;        }        if(n == 1)        {            printf("%d\n",sum);        }        else        {            printf("-1\n");        }    }    return 0;}
用n判环依旧超

超时代码3:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;int pre[510];struct node{    int left,right,value;}a[25010];int cmp(const void *_a,const void *_b){    struct node *a = (node*)_a;    struct node *b = (node*)_b;    return a->value - b->value;}int findroot(int x){    return x == pre[x] ? x : pre[x] = findroot(pre[x]);//求根节点加路径压缩}int main(){    int t,n,m,k;    int i,j;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&m,&k);        for(i=1; i<=n; i++)        {            pre[i] = i;        }        for(i=0; i<m; i++)        {            scanf("%d%d%d",&a[i].left,&a[i].right,&a[i].value);        }        qsort(a,m,sizeof(node),cmp);        int sum,l,x;        int root1,root2;        for(i=0; i<k; i++)        {            scanf("%d",&sum);            scanf("%d",&l);            root1 = findroot(l);            for(j=1; j<sum; j++)            {                scanf("%d",&x);                root2 = findroot(x);                if(root1 != root2)                {                    pre[root2] = pre[root1];                    n--;                }            }        }        sum = 0;        for(i=0; i<m; i++)        {            if(pre[a[i].left] != pre[a[i].right])            {                pre[pre[a[i].left]] = pre[a[i].right];                sum += a[i].value;                n--;            }            if(n == 1)                break;        }        if(n == 1)        {            printf("%d\n",sum);        }        else        {            printf("-1\n");        }    }    return 0;}
减少函数调用依旧超时



0 0
原创粉丝点击