备战蓝桥杯---图论应用1

目录

1.增加虚点建图:

2.抽象图的迪杰斯特拉:

3.用bitset优化弗洛伊德:

4.有向图的Prim/kruskal:


1.增加虚点建图:

我们当然可以每一层与上一层的点再连上一条边,但这样子边太多了超内存,我们可以对于每一层建立两个虚的中站,其中一个每一层的点到中站的距离=0,他连一条边与上面的站,权值为两层的距离,另一个向下(注意边都是单向边,否则会产生新的路径)。

2.抽象图的迪杰斯特拉:

每一个集合里如果互相连边的话边太多了,我们不妨把一个集合当成一个抽象的点,然后去跑迪杰斯特拉。因此我们只要记录每一个点属于的集合以及每一个集合中含有的点即可。

我们还是在枚举点,只不过我们要再多一个for来表示取出的集合,同时我们保证集合只被枚举一次,因为重复的集合不会使结果更优。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t,n,m,t1[100010],ti,si,k;
vector<int> es[1000005];
vector<int> inque[100005];
int dis[2][100010];
bool vistuan[100010],visdian[100010];
int ans[100010];
struct node{int zhi,dian;bool operator<(const node &a) const{return zhi>a.zhi;}
};
priority_queue<node> q;
void dij(int s,int f){memset(vistuan,0,sizeof(vistuan));memset(visdian,0,sizeof(visdian));dis[f][s]=0;q.push({0,s});while(!q.empty()){node ck=q.top();q.pop();if(visdian[ck.dian]==1) continue;visdian[ck.dian]=1;for(int i=0;i<inque[ck.dian].size();i++){int j=inque[ck.dian][i];if(vistuan[j]==1) continue;vistuan[j]=1;for(int k=0;k<es[j].size();k++){int w=es[j][k];if(visdian[w]==1) continue;if(dis[f][w]>ck.zhi+t1[j]){dis[f][w]=ck.zhi+t1[j];q.push({dis[f][w],w});}}}}
}
signed main(){cin>>t;int i1=1;while(t--){scanf("%lld%lld",&n,&m);for(int i=1;i<=n;i++) inque[i].clear();memset(dis,0x7f7f7f7f,sizeof(dis));for(int i=1;i<=m;i++){es[i].clear();scanf("%lld%lld",&ti,&si);t1[i]=ti;for(int j=1;j<=si;j++){scanf("%lld",&k);es[i].push_back(k);inque[k].push_back(i);}}dij(1,0);dij(n,1);long long ans_tmp=1e18;int ans_len=0;for(int i=1;i<=n;i++){if(max(dis[0][i],dis[1][i])<ans_tmp){ans_tmp=max(dis[0][i],dis[1][i]);ans_len=0;ans[ans_len++]=i;}else if(max(dis[0][i],dis[1][i])==ans_tmp){ans[ans_len++]=i;}}printf("Case #%d: ",i1++);if(ans_len==0||ans_tmp==1e18){printf("Evil John\n");}else{printf("%lld\n",ans_tmp);for(int i=0;i<ans_len;i++){printf("%lld",ans[i]);if(i==ans_len-1)printf("\n");elseprintf(" ");}}}}

3.用bitset优化弗洛伊德:

我们把>号表示成一条有向边即可。这样子我们就是求任意两点是否可以到,我们很容易想到弗洛伊德算法,但是这个复杂度铁超,我们发现,弗洛伊德还算出了最短距离,而我们只需要0/1,因此我们想到bitset优化,我们把每一个点能否到其他点记作01串,这样子当我们枚举中转使,只要或上中转的01串即可。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
struct node{int dian,next;
}edge[100010];
bitset<1005> dp[1010];
int n,m,head[1010],cnt,x,y;
void merge(int x,int y){edge[++cnt].dian=y;edge[cnt].next=head[x];head[x]=cnt;
}
int main(){cin>>n>>m;memset(head,-1,sizeof(head));for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);merge(x,y);dp[x][y]=1;}for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){if(i==k) continue;if(dp[i][k]==0) continue;dp[i]|=dp[k];}}int ans=0;for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){if(dp[i][j]==1||dp[j][i]==1) continue;ans++;}}cout<<ans;
}

4.有向图的Prim/kruskal:

显然,我们先建个由高度决定的有向边,我们再跑一个DFS,记录哪个点可否到达,这样子,我们就可以得到类似于树的结构,假如他是无向边,我们就是求个最小生成树,但是因为是有向边,我们不可以直接跑这两个算法,我们不妨想想是为什么?

其实,问题就在于你无法保证那条连的边是可以按照正确方向走的,或者说,按照他走可能走不通,而这是由高度造成的,于是我们可以按照高度,从上到下建立关系,我们不妨先看1,2层,当他们建好时再考虑第3层,依次类推即可。

如果用Prim算法,我们只需先按照高度排序即可。

如果用kruskal算法,我们在存边时在记录下两者中较低的高度sort即可。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,h[100010],vis[100010],u,v,k,cnt,fa[100010];
struct node{int x,y,z,h;
}bian[1000100];
vector<int> edge[1000100];
void dfs(int ck){cnt++;vis[ck]=1;for(int i=0;i<edge[ck].size();i++){int yy=edge[ck][i];if(vis[yy]==1) continue;dfs(yy);}return;
}
bool cmp(node a,node b){if(a.h==b.h) return a.z<b.z;return a.h>b.h;
}
int find(int x){if(fa[x]==x) return x;return fa[x]=find(fa[x]);
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%d",&h[i]);for(int i=1;i<=m;i++){scanf("%d%d%d",&u,&v,&k);if(h[u]>h[v]) edge[u].push_back(v);else if(h[u]<h[v]) edge[v].push_back(u);else{edge[u].push_back(v);edge[v].push_back(u);}bian[i].x=u;bian[i].y=v;bian[i].z=k;bian[i].h=min(h[u],h[v]);}dfs(1);cout<<cnt<<" ";long long ans=0;for(int i=1;i<=n;i++) fa[i]=i;sort(bian+1,bian+m+1,cmp);for(int i=1;i<=m;i++){int xx=bian[i].x;int yy=bian[i].y;if(vis[xx]==0||vis[yy]==0) continue;int xxx=find(xx);int yyy=find(yy);if(xxx==yyy) continue;ans+=bian[i].z;fa[xxx]=yyy;}cout<<ans;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/511771.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【格与代数系统】偏序关系、偏序集与全序集

关系&#xff1a;X,Y是两个非空集合, 记若则称R是X到Y的一个二元关系&#xff0c;简称关系。 若,记。 当时&#xff0c;称是上的一个关系。 目录 偏序关系 偏序集 可比性 全序集 最值与上下界 上下确界 偏序关系 设是上的一个关系&#xff0c;若满足&#xff1a; (1)自…

springboot+bootstrap+jsp校园二手书交易平台mlg86

考虑到实际生活中在校园二手书交易系统方面的需要以及对该系统认真的分析,将系统权限按管理员和学生这两类涉及用户划分。 (a) 管理员&#xff1b;管理员使用本系统涉到的功能主要有个人中心、学生管理、图书类型管理、二手图书管理、通知公告管理、管理员管理、用户留言、系统…

微信小程序开发学习笔记《19》uni-app框架-配置小程序分包与轮播图跳转

微信小程序开发学习笔记《19》uni-app框架-配置小程序分包与轮播图跳转 博主正在学习微信小程序开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读uni-app对应官方文档 一、配置小程序分包 分包可以减少小程序首次启动时的加载时间 为此&#…

idea中引入新JDK环境

在不同的项目中往往会需要不同的运行环境&#xff0c;那么如何下载一个新的环境并运用到idea中呢&#xff1f; 下面给出的就是oracle官网&#xff0c;以JDK17为例教大家如何下载 Java Archive Downloads - GraalVM for JDK 17https://www.oracle.com/java/technologies/javase…

钉钉h5应用 环境报错Error: Do not support the current environment:notInDingTalk

钉钉h5应用 环境报错 Error: Do not support the current environment&#xff1a;notInDingTalk problem Error: Do not support the current environment&#xff1a;notInDingTalk reason 前端页面运行在普通浏览器 solution 需要将h5页面在后台发布后&#xff0c;在钉…

CodeFlying 和 aixcoder两大免费软开平台,孰强孰弱?

今天为大家带来码上飞CodeFlying和aixcoder两款免费的软件开发平台效果的测评 一、产品介绍 首先简单介绍一下这两个平台 码上飞CodeFlying&#xff1a;码上飞 CodeFlying | AI 智能软件开发平台&#xff01; 是一款革命性的软件开发平台&#xff0c;它通过将软件工程和大模…

CSS变量和@property

CSS变量 var() CSS 变量是由CSS作者定义的实体&#xff0c;其中包含要在整个文档中重复使用的特定值。使用自定义属性来设置变量名&#xff0c;并使用特定的 var() 来访问。&#xff08;比如 color: var(--main-color);&#xff09;。 基本用法 CSS变量定义的作用域只在定义该…

白银期货开户交割规则有哪些?

白银期货交割是指期货合约到期时&#xff0c;交易双方通过该期货合约所载商品所有权的转移&#xff0c;了结到期未平仓合约的过程。小编在此为大家详细介绍白银期货的交割规则有哪些。白银期货的交割规则有哪些&#xff1f;白银期货的交割规则主要有&#xff1a; 一、交割商品…

nodejs,JSDOM 补 window环境

window[atob] 是一个在浏览器中使用的 JavaScript 函数&#xff0c;用于将 base64 编码的字符串解码为原始数据。具体来说&#xff0c;atob 函数会将 base64 字符串解码为一个 DOMString&#xff0c;其中包含解码后的二进制数据。这在处理从服务器获取的 base64 编码的数据或在…

2024 中国(南京)国际口腔设备器械博览会

2024 中国&#xff08;南京&#xff09;国际口腔设备器械博览会 时间&#xff1a;2024 年 7 月 18-20 日 地点&#xff1a;南京国际展览中心 主办单位: 南京民营口腔医疗协会 北京铭曼国际展览有限公司 承办单位: 北京铭曼国际展览有限公司 展会介绍 随着人类社会的不断进步和…

什么是Docker容器?

Docker是一种轻量级的虚拟化技术&#xff0c;同时是一个开源的应用容器运行环境搭建平台&#xff0c;可以让开发者以便捷方式打包应用到一个可移植的容器中&#xff0c;然后安装至任何运行Linux或Windows等系统的服务器上。相较于传统虚拟机&#xff0c;Docker容器提供轻量化的…

微信小程序用户隐私保护指引设置

场景&#xff1a;开发小程序时&#xff0c;有时候需要获取用户隐私信息&#xff0c;在提交小程序审核时&#xff0c;需要填写一份隐私保护协议&#xff0c;经常由于填写不规范导致审核不通过&#xff0c;在网上找到了一份模块可供参考 步骤&#xff1a;小程序后台-》设置-》服…