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[]=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(最小生成树)的更多相关文章
- 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 ...
- ZOJ 3204 Connect them(最小生成树+最小字典序)
Connect them Time Limit: 1 Second Memory Limit: 32768 KB You have n computers numbered from 1 t ...
- ZOJ 3204 Connect them(字典序输出)
主要就是将最小生成树的边按字典序输出. 读取数据时,把较小的端点赋给u,较大的端点号赋值给v. 这里要用两次排序,写两个比较器: 第一次是将所有边从小到大排序,边权相同时按u从小到大,u相同时按v从小 ...
- ZOJ 3204 Connect them MST-Kruscal
这道题目麻烦在输出的时候需要按照字典序输出,不过写了 Compare 函数还是比较简单的 因为是裸的 Kruscal ,所以就直接上代码了- Source Code : //#pragma comme ...
- zoj 3204 Connect them
最小生成树,我用的是并查集+贪心的写法. #include<stdio.h> #include<string.h> #include<math.h> #includ ...
- ZOJ 3204 Connect them 继续MST
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3367 题目大意: 让你求最小生成树,并且按照字典序输出哪些点连接.无解输出-1 ...
- zoj 3204 最小生成树,输出字典序最小的解
注意排序即可 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring ...
- zoj3204 connect them 最小生成树 暴力
Connect them Time Limit: 1 Second Memory Limit:32768 KB You have n computers numbered from 1 to ...
- ZOJ 1586 QS Network (最小生成树)
QS Network Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Sta ...
随机推荐
- 【shell】shell编程(三)-if,select,case语句
通过前两篇文章,我们掌握了shell的一些基本写法和变量的使用,以及基本数据类型的运算.那么,本次就将要学习shell的结构化命令了,也就是我们其它编程语言中的条件选择语句及循环语句. 不过,在学习s ...
- Python入门--5--列表
python没有数组 蛋是有列表 列表里面可以有:整数,浮点数,字符串,对象 没有数组,没有数组,没有数组,不重要的也说三遍!! 一.创建列表 x = ['abc','sas','www'] ...
- Day 11 正则表达式
正则表达式 一.简介 Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配到的行打印出来.grep全称是Globally search for a Regular ...
- 用“道”的思想解决费用流问题---取/不取皆是取 (有下界->有上界) / ACdreamoj 1171
题意: 给一个矩阵,给出约束:i(0<i<n)行至少去ai个数,j行至少取bi个数,要求取的数值之和最小. 开始一见,就直接建了二分图,但是,发现这是有下界无上界最小费用流问题,肿么办.. ...
- luogu P1149 火柴棒等式
题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 加号与等号各自 ...
- Java网络编程之InetAddress和URL
在Java中提供了专门的网络开发程序包---java.net,java的网络编程提供了两种通信协议:TCP(传输控制协议)和UDP(数据报协议). 一.IP(Internet Protocol) 与I ...
- NRapid前言
开发工具 Visual Studio 2017 数据库 SQL Server 2012 相关技术 Asp.net MVC
- docker 配置 direct-lvm
当前需要设置的宿主机是环境是搭建在vbox虚拟机上的centos7系统.测试环境中出现过一次意外情况,当时为了测试docker日志文件限制,运行了一个docker容器,但是后面忘记停止了,几天后发现了 ...
- 【PostgreSQL】安装使用步骤
1.下载地址 https://www.postgresql.org/download/windows/ 下载按照较新版本,和平台相一致就好 2.安装 选择安装地址 数据存放地址 密码设置 端口使用默认 ...
- Python机器学习--降维
主成分分析(PCA) 测试 # -*- coding: utf-8 -*- """ Created on Thu Aug 31 14:21:51 2017 @author ...