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

思路:模板

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[]=true;
for(i=;i<n;++i){
lowu[i]=;//起始边都为0
lowc[i]=cost[][i];
}
for(i=;i<n;++i){
minc=INF;
p=-;
for(j=;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]+;
ans[cnt++].v=p+;
}
else{
ans[cnt].u=p+;
ans[cnt++].v=lowu[p]+;
} vis[p]=true;
for(j=;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=;i<n;++i)
for(j=;j<n;++j){
scanf("%d",&w);
if(w==)w=INF;
cost[i][j]=w;
} cnt=;
if(prim(cost,n)){
sort(ans,ans+cnt,cmp);//字典序
for(i=;i<cnt-;++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 ;
}

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]==-)return x;
return F[x]=find(F[x]);
} //传入点数,返回最小生成树的权值,如果不连通返回-1
void kruskal(int n){
memset(F,-,sizeof(F));
sort(edge,edge+tol,cmp); int i,u,v,w,t1,t2;
for(i=;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-)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=;cnt=;
for(i=;i<=n;++i)
for(j=;j<=n;++j){
scanf("%d",&w);
if(j<=i)continue;
if(w==)continue;
addedge(i,j,w);
} kruskal(n);
if(cnt!=n-)printf("-1\n");
else{
sort(ans,ans+cnt,cmp2);//此处控制输出排序
for(i=;i<cnt-;++i)
printf("%d %d ",ans[i].u,ans[i].v);
printf("%d %d\n",ans[i].u,ans[i].v);
}
}
return ;
}

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

  1. ZOJ - 3204 Connect them 最小生成树

    Connect them ZOJ - 3204 You have n computers numbered from 1 to n and you want to connect them to ma ...

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

    Connect them Time Limit: 1 Second      Memory Limit: 32768 KB You have n computers numbered from 1 t ...

  3. ZOJ 3204 Connect them(字典序输出)

    主要就是将最小生成树的边按字典序输出. 读取数据时,把较小的端点赋给u,较大的端点号赋值给v. 这里要用两次排序,写两个比较器: 第一次是将所有边从小到大排序,边权相同时按u从小到大,u相同时按v从小 ...

  4. ZOJ 3204 Connect them MST-Kruscal

    这道题目麻烦在输出的时候需要按照字典序输出,不过写了 Compare 函数还是比较简单的 因为是裸的 Kruscal ,所以就直接上代码了- Source Code : //#pragma comme ...

  5. zoj 3204 Connect them

    最小生成树,我用的是并查集+贪心的写法. #include<stdio.h> #include<string.h> #include<math.h> #includ ...

  6. ZOJ 3204 Connect them 继续MST

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3367 题目大意: 让你求最小生成树,并且按照字典序输出哪些点连接.无解输出-1 ...

  7. zoj 3204 最小生成树,输出字典序最小的解

    注意排序即可 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring ...

  8. zoj3204 connect them 最小生成树 暴力

    Connect them Time Limit: 1 Second      Memory Limit:32768 KB You have n computers numbered from 1 to ...

  9. ZOJ 1586 QS Network (最小生成树)

    QS Network Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Sta ...

随机推荐

  1. linux磁盘I/O的性能评估

    linux磁盘I/O的性能评估 参考自:自学it网,http://www.zixue.it/. (1)使用iostat命令. [test@localhost /]$ iostat -d Linux - ...

  2. ****如何优雅的用Axure装逼?高保真原型心得分享

    本文核心内容点:- 啥是高保真原型?(附简单说明原型)- Axure可以画出什么水准的高保真?(给示例,开启装逼模式)- 高保真原型图技巧:- 啥时候上高保真?适用场景 and 不适用场景 啥是高保真 ...

  3. 计算机操作系统处理机调度读后感—–关于进程概念的剖析。从RING3到RING0(32位操作系统)

    计算机操作系统处理机调度读后感: 笔者在看操作系统西安电子科技大学那本书的时候,初次感觉本科教的不会太难,所以没有认真的看,但是随后这本书讲的刷新了我的世界观.这本书居然是ring0级别的,这时不禁吐 ...

  4. Delphi GDI对象之绘制文本

    转载:http://www.cnblogs.com/pchmonster/archive/2012/07/06/2579185.html 基本绘图操作(Basic Drawing Operations ...

  5. 基于MNIST数据的卷积神经网络CNN

    基于tensorflow使用CNN识别MNIST 参数数量:第一个卷积层5x5x1x32=800个参数,第二个卷积层5x5x32x64=51200个参数,第三个全连接层7x7x64x1024=3211 ...

  6. c程序设计语言第一章3

    字符数组是C语言中最常用的数组类型.下面我们通过编写一个程序,来说明字符数组以反操作字符数组的函数的用法.该程序读入一组文本行,并把最长的文水行打印出来.该算法的基本框架非常简单: while (还有 ...

  7. struts2_13_OGNL表达式

    全称:Object Graphic Navigation Language(对象图导航语言)是一个开源项目,是Struts2框架的默认表达式语言. 相对于EL表达式.它提供了平时我们须要的一些功能,如 ...

  8. uboot1.1.6中启动流程

    U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶段的功能 Ø 硬件设备初始化 Ø 加载U-Boot第二阶段代码到RAM空间 Ø 设置好栈 Ø 跳转到第二阶段代码入口 (2 ...

  9. QEMU+GDB调试方法

    两年前调试usb/ip开源项目时,就曾用虚拟机远程调试过Windows和Linux系统内核,当时在VMware Workstation上创建两个虚拟机进行调试,也没有记录下如何配置调试,只是大体的还记 ...

  10. windows下使用F2PY编译fortran文件的问题

    在windo系统下F2PY不支持gcc+gfortran的组合,解决的办法: 1.安装mingw和msys,在msys环境下使用F2PY调用gcc+gfortran进行编译 2.放弃F2PY,直接gf ...