HDU 1102

来源:互联网 发布:windows xp 下载 编辑:程序博客网 时间:2024/05/21 12:39
最小生成树

对于必须要加入的边, 让其边权为0 即可

Prim :

#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int maxn = 100 + 31;const int INF=0x3f3f3f3f;int Map[maxn][maxn];int Vis[maxn], Dis[maxn];int ans;int n;void Prim(){    int k;    for(int i = 1; i <= n; ++i)        Dis[i] = Map[1][i], Vis[i] = 0;    Dis[1] = 0;    Vis[1] = 1;    for(int i = 1; i <= n; ++i)    {        int tmp = INF;        for(int j = 1; j <= n; ++j)            if(Vis[j] == 0 && tmp > Dis[j]) tmp = Dis[j], k = j;        if(tmp == INF) break;        Vis[k] = 1;        ans += Dis[k];        for(int j = 1; j <= n; ++j)            if(Vis[j] == 0 && Dis[j] > Map[k][j]) Dis[j] = Map[k][j];    }}int main(){    while(~scanf("%d",&n))    {        ans = 0;        //memset(Map,INF,sizeof(Map));        for(int i = 1; i <= n; ++i)            for(int j = 1; j <= n; ++j)            scanf("%d",&Map[i][j]);        int q,a,b;        scanf("%d",&q);        while(q--)        {            scanf("%d%d",&a,&b);            Map[a][b] = Map[b][a] = 0;        }        Prim();        printf("%d\n",ans);    }    return 0;}

\

Kruskal :

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>using namespace std;const int maxn = 100 + 7;struct Edges{    int u, v;    int val;}edges[maxn * maxn];int Pre[maxn];int n,cnt,ans;void Add_Edge(int u,int v,int val){    edges[cnt].u = u, edges[cnt].v = v, edges[cnt].val = val;    cnt ++;}void Init(){    for(int i = 0; i < maxn ; ++i) Pre[i] = i;    cnt = 0;    ans = 0;}int Find(int x){    int r = x;    while(r != Pre[r]) r = Pre[r];    return Pre[x] = r;}bool Union(int x,int y){    int ax = Find(x), ay = Find(y);    if(ax == ay) return false;    Pre[ax] = ay;    return true;}bool cmp(Edges a, Edges b){    return a.val < b.val;}void Kruskal(){    sort(edges,edges+cnt,cmp);    for(int i = 0; i < cnt; ++i)    {        if(Union(edges[i].u,edges[i].v)) ans += edges[i].val;    }}int main(){    int n;    while(~scanf("%d",&n))    {        Init();        int a, b, q;        for(int i = 1; i <= n; ++i)            for(int j = 1; j <= n; ++j)            {                scanf("%d",&a);                Add_Edge(i,j,a);            }        scanf("%d",&q);        while(q--)        {            scanf("%d%d",&a,&b);            a = Find(a);            b = Find(b);            Pre[a] = b;        }        Kruskal();        printf("%d\n",ans);    }    return 0;}

第一道最小生成树,纪念一下。。

0 0
原创粉丝点击