博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[poj1797]Heavy Transportation<最大生成树prim&kruskal>
阅读量:6174 次
发布时间:2019-06-21

本文共 3350 字,大约阅读时间需要 11 分钟。

题目链接:http://poj.org/problem?id=1797

题意:给定n个点,m条边,每条边连接两点切有权值。求点1到点n的路径的上的最小边的值最大。。。

翻别人博客找到的题,方法挺多的,直接跑一个最大生成树就行,或者是一个最短路算法也行

我自己用了prim和kruskal 的方法来做

虽然用最短路也可以轻松过,但是我还是选择了生成树

 

prim

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #define maxn 1005 9 using namespace std;10 struct node{11 int u,v,w,nxt;12 }e[maxn*maxn];13 14 int n,m,low[maxn],mst[maxn],head[maxn],vis[maxn],ans;15 16 int read(){17 int x=0,f=1;char ch=getchar();18 while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar();}19 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}20 return x*f;21 }22 23 int tot;24 void adde(int u,int v,int w){25 e[tot]=(node){u,v,w,head[u]};26 head[u]=tot++;27 }28 29 void first(){30 ans=1000000001;31 memset(low,0,sizeof(low));32 memset(mst,0,sizeof(mst));33 memset(head,-1,sizeof(head));34 memset(vis,0,sizeof(vis));tot=0 ; 35 }36 37 void prim(int num){38 int u=1,maxx=-ans,maxid;39 for(int i=head[u];i!=-1;i=e[i].nxt){40 int v=e[i].v;41 mst[v]=u;low[v]=e[i].w;42 }vis[u]=1;43 int nn=n-1;44 while(nn--){45 for(int i=1;i<=n;i++){46 if(low[i]&&mst[i]){47 if(low[i]>maxx){48 maxx=low[i];maxid=i;49 }50 }51 }52 ans=min(maxx,ans);maxx=0;53 low[maxid]=0;mst[maxid]=0;vis[maxid]=1;54 if(maxid==n)break;55 for(int i=head[maxid];i!=-1;i=e[i].nxt){56 int v=e[i].v;57 if(e[i].w>low[v]&&!vis[v]){58 mst[v]=maxid;low[v]=e[i].w;59 }60 } 61 }62 printf("Scenario #%d:\n%d\n\n",num,ans);63 }64 65 int main(){66 int T;T=read();int h=0;67 while(T--){68 first();h++;69 n=read();m=read();70 for(int i=1;i<=m;i++){71 int u,v,w;72 u=read();v=read();w=read();73 adde(u,v,w);adde(v,u,w);74 }75 prim(h); 76 }77 }
View Code

kruskal

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #define maxn 1005 9 using namespace std;10 11 struct node{12 int u,v,w,nxt;13 }e[maxn*maxn];14 15 int n,m,fa[maxn],sum,ans,vis[maxn];16 17 int tot;18 void adde(int u,int v,int w){19 e[tot]=(node){u,v,w};20 tot++;21 }22 23 void first(){24 ans=1000000001;sum=0;tot=0;25 for(int i=1;i<=n;i++)fa[i]=i;26 }27 28 int find(int x){29 if(fa[x]==x)return x;30 return fa[x]=find(fa[x]);31 }32 33 int comp(const void*a,const void*b){34 return (*(struct node*)a).w<(*(struct node*)b).w?1:-1;35 }36 37 int read(){38 int xx=0,ff=1;char ch=getchar();39 while(ch<'0'||ch>'9'){ if(ch=='-')ff=-1;ch=getchar();}40 while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}41 return xx*ff;42 }43 44 int can(int x,int y){45 int fx=find(x),fy=find(y);46 if(fx!=fy)return 0;47 return 1;48 }49 50 int main(){51 int T,k=0;T=read();52 while(T--){53 k++;n=read();m=read();54 first();memset(vis,0,sizeof(vis));55 for(int i=1;i<=m;i++){56 int u=read(),v=read(),w=read();57 adde(u,v,w);adde(v,u,w);58 }e[0].w=ans;59 qsort(e+1,tot+1,sizeof(e[0]),comp);60 for(int i=1;i<=tot;i++){61 int u=e[i].u,v=e[i].v;62 int fu=find(u),fv=find(v);63 if(fu!=fv){64 fa[fv]=fu;ans=min(ans,e[i].w);65 }66 if(can(1,n)){67 printf("Scenario #%d:\n%d\n\n",k,ans);break;68 }69 }70 }71 }
View Code

PS:注意一下输出的格式,容易错的。

还有就是判断算法的结束条件,并不是当所有的点都加入了,而是当1能到n 的时候就可以跳出了

 

 

转载于:https://www.cnblogs.com/Danzel-Aria233/p/7785558.html

你可能感兴趣的文章
5. GC 调优(基础篇) - GC参考手册
查看>>
Windows 7 XP 模式颜色质量只有16位的解决
查看>>
SonicWall如何安全模式升级防火墙
查看>>
Linux IPC实践(3) --具名FIFO
查看>>
从Atlas到Microsoft ASP.NET AJAX(6) - Networking, Application Services
查看>>
成长之路---写好一个类
查看>>
读取 java.nio.ByteBuffer 中的字符串(String) 写入方式flash.utils.ByteArray.writeUTF
查看>>
范围管理和范围蔓延
查看>>
android90 bind方式启动服务service调用service里的方法
查看>>
前端开发薪资之各地区对比(图文分析)(share)
查看>>
对做“互联网产品”的一些想法
查看>>
SPI协议及其工作原理浅析【转】
查看>>
原生js编写的安全色拾色器
查看>>
iOS:VFL语言
查看>>
让时间处理简单化 【第三方扩展类库org.apache.commons.lang.time】
查看>>
用scikit-learn学习DBSCAN聚类
查看>>
Linux设备模型(热插拔、mdev 与 firmware)【转】
查看>>
Android开发笔记第二篇(Android 手机概念)
查看>>
js隐藏与显示回到顶部按钮
查看>>
hdu4496 D-City(扭转和支票托收啊 )
查看>>