zoj 3204 Connect them(最小生成树)

题意:裸最小生成树,主要是要按照字典序。

思路:模板

prim:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define INF 0x7fffffff
#define MAXN 128
bool vis[MAXN];
int lowu[MAXN];//记录起始边(已加入集合中的边)
int lowc[MAXN];

struct Edge{
    int u,v;
};
Edge ans[MAXN*MAXN];
int cnt;//边数

bool cmp(Edge a,Edge b){
    if(a.u!=b.u)return a.u<b.u;
    return a.v<b.v;
}

bool prim(int cost[][MAXN],int n){//标号从0开始
    int i,j,minc,p;
    memset(vis,false,sizeof(vis));
    vis[0]=true;
    for(i=1;i<n;++i){
        lowu[i]=0;//起始边都为0
        lowc[i]=cost[0][i];
    }
    for(i=1;i<n;++i){
        minc=INF;
        p=-1;
        for(j=0;j<n;++j)
            if(!vis[j]&&(lowc[j]<minc||(lowc[j]==minc&&lowu[j]<p))){//字典序
                minc=lowc[j];
                p=j;
            }
        if(minc==INF)return false;//原图不连通

        if(lowu[p]<p){
            ans[cnt].u=lowu[p]+1;
            ans[cnt++].v=p+1;
        }
        else{
            ans[cnt].u=p+1;
            ans[cnt++].v=lowu[p]+1;
        }

        vis[p]=true;
        for(j=0;j<n;++j)
            if(!vis[j]&&(cost[p][j]<lowc[j]||(cost[p][j]==lowc[j]&&p<lowu[j]))){//字典序
                lowu[j]=p;//起始边变为p
                lowc[j]=cost[p][j];
            }
    }
    return true;
}

int main(){
    int t;
    int n,m,a,b,w,i,j;
    int cost[MAXN][MAXN];
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        //m=n*(n-1)/2;//m边条数
        for(i=0;i<n;++i)
            for(j=0;j<n;++j){
                scanf("%d",&w);
                if(w==0)w=INF;
                cost[i][j]=w;
            }

        cnt=0;
        if(prim(cost,n)){
            sort(ans,ans+cnt,cmp);//字典序
            for(i=0;i<cnt-1;++i)
                printf("%d %d ",ans[i].u,ans[i].v);
            printf("%d %d\n",ans[i].u,ans[i].v);
        }
        else printf("-1\n");
    }
    return 0;
}

kruskal:注意sort排序是不稳定排序,那么cmp中的w相同时怎么排要指出。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define MAXN 110//最大点数
#define MAXM 10000//最大边数
int F[MAXN];//并查集使用

struct Edge{
    int u,v,w;
}edge[MAXM];//存储边的信息,包括起点/终点/权值
int tol;//边数,加边前赋值为0
int cnt;//计算加入的边数
Edge ans[MAXM];//存储结果

void addedge(int u,int v,int w){
    edge[tol].u=u;
    edge[tol].v=v;
    edge[tol++].w=w;
}

//排序函数,将边按照权值从小到大排序
bool cmp(Edge a,Edge b){//sort排序不稳定
    if(a.w!=b.w)return a.w<b.w;
    if(a.u!=b.u)return a.u<b.u;
    return a.v<b.v;
}

bool cmp2(Edge a,Edge b){
    if(a.u!=b.u)return a.u<b.u;
    return a.v<b.v;
}

int find(int x){
    if(F[x]==-1)return x;
    return F[x]=find(F[x]);
}

//传入点数,返回最小生成树的权值,如果不连通返回-1
void kruskal(int n){
    memset(F,-1,sizeof(F));
    sort(edge,edge+tol,cmp);

    int i,u,v,w,t1,t2;
    for(i=0;i<tol;++i){
        u=edge[i].u;
        v=edge[i].v;
        w=edge[i].w;
        t1=find(u);
        t2=find(v);
        if(t1!=t2){
            ans[cnt++]=edge[i];
            F[t1]=t2;
        }
        if(cnt==n-1)break;
    }
//    if(cnt<n-1)return -1;//不连通
//    return ans;
}

int main(){
    int t;
    int n,m,a,b,w,i,j;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        //m=n*(n-1)/2;//m边条数
        tol=0;cnt=0;
        for(i=1;i<=n;++i)
            for(j=1;j<=n;++j){
                scanf("%d",&w);
                if(j<=i)continue;
                if(w==0)continue;
                addedge(i,j,w);
            }

        kruskal(n);
        if(cnt!=n-1)printf("-1\n");
        else{
            sort(ans,ans+cnt,cmp2);//此处控制输出排序
            for(i=0;i<cnt-1;++i)
                printf("%d %d ",ans[i].u,ans[i].v);
            printf("%d %d\n",ans[i].u,ans[i].v);
        }
    }
    return 0;
}

时间: 2024-10-11 02:26:23

zoj 3204 Connect them(最小生成树)的相关文章

ZOJ 3204 Connect them (C) 最小生成树kruskal

Connect them Time Limit: 1 Second      Memory Limit: 32768 KB You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN). All connections are two-way (that is connecting computers i and j is the sa

ZOJ 3204 Connect them(最小生成树:kruscal算法)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3204 Connect them Time Limit: 1 Second     Memory Limit:32768 KB You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN).All connecti

ZOJ 3204 Connect them(最小生成树之Krusal 输出字典序最小的)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3367 You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN). All connections are two-way (that is connecting computers i and j is

ZOJ 3204 Connect them(最小生成树+最小字典序)

Connect them Time Limit: 1 Second      Memory Limit: 32768 KB You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN). All connections are two-way (that is connecting computers iand j is the sam

ZOJ 3204 Connect them MST-Kruscal

这道题目麻烦在输出的时候需要按照字典序输出,不过写了 Compare 函数还是比较简单的 因为是裸的 Kruscal ,所以就直接上代码了- Source Code : //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <fstream> #include <cstring

ZOJ 3204: Connect Them

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3367 #include <iostream> #include <algorithm> #include <limits> #include <queue> using namespace std; const int MAXN = 105, INF = numeric_limits<int>::max(); typedef

POJ 1861 &amp; ZOJ 1542 Network(最小生成树之Krusal)

题目链接: PKU:http://poj.org/problem?id=1861 ZJU:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=542 Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the c

zoj 1203 Swordfish 【最小生成树 prim 算法】

Swordfish Time Limit: 2 Seconds      Memory Limit: 65536 KB There exists a world within our world A world beneath what we call cyberspace. A world protected by firewalls, passwords and the most advanced security systems. In this world we hide our dee

POJ 1861 &amp;amp; ZOJ 1542 Network(最小生成树之Krusal)

题目链接: PKU:http://poj.org/problem?id=1861 ZJU:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=542 Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the c