hdu 1102

来源:互联网 发布:库存查询软件 编辑:程序博客网 时间:2024/05/21 13:01

最小生成树
一.prime 算法
直接暴力每个点,以每个点为起点找出最优解(距离最短)

#include <bits/stdc++.h>using namespace std;typedef __int64 ll;const int N=107,INF=0x3f3f3f3f;int cost[N][N],lc[N],vis[N];int n;int prime(){    for(int i=1; i<=n; i++)    {        int mi=INF,pos;        for(int j=1; j<=n; j++)            if(!vis[j]&&mi>lc[j])                mi=lc[j],pos=j;        vis[pos]=1;//找出花费最少的点后,标记掉避免二次计算        for(int j=1; j<=n; j++)            if(!vis[j]&&lc[j]>cost[j][pos])                lc[j]=cost[j][pos];    }    int ans=0;    for(int i=1; i<=n; i++)        ans+=lc[i];//答案为每个点的花费总和    return ans;}int main(){    int q;    while(~scanf("%d",&n))    {        for(int i=1; i<=n; i++)            for(int j=1; j<=n; j++)                scanf("%d",&cost[i][j]);  //i->j的花费        scanf("%d",&q);        for(int i=0; i<q; i++)        {            int a,b;            scanf("%d%d",&a,&b);            cost[a][b]=0;            cost[b][a]=0;        }        memset(lc,INF,sizeof(lc));//每个点的最低花费        memset(vis,0,sizeof(vis));//是否访问过这个点        lc[1]=0;//起点花费为0        printf("%d\n",prime());    }}

二 . kruskal
已经连接的点并入一个集合(并查集)

#include <bits/stdc++.h>using namespace std;typedef __int64 ll;const int N=107,INF=0x3f3f3f3f;int f[N],k;struct node{    int s,d,co;} po[N*N];int _find(int x){    if(f[x]!=x) return f[x]=_find(f[x]);    return f[x];}int cmp(node a,node b){    return a.co<b.co;}int kruskal(){    int ans=0;    for(int i=0; i<k; i++)    {        int fa=_find(po[i].s);        int fb=_find(po[i].d);        if(fa!=fb)//不在一个集合内就放入并建边,费用放进ans        {            ans+=po[i].co;            f[fa]=fb;        }    }    return ans;}int main(){    int n,q;    while(~scanf("%d",&n))    {        k=0;        for(int i=0; i<=n; i++)            f[i]=i;        for(int i=1; i<=n; i++)            for(int j=1; j<=n; j++)            {                scanf("%d",&po[k].co);                po[k].s=i,po[k].d=j;                k++;            }        int q;        scanf("%d",&q);        for(int i=0; i<q; i++)        {            int a,b;            scanf("%d%d",&a,&b);            int fa=_find(a);            int fb=_find(b);            if(fa!=fb) f[fa]=fb;//已经建好的路放进一个集合        }        sort(po,po+k,cmp);//按照花费从小到大排序        printf("%d\n",kruskal());    }}