zoukankan      html  css  js  c++  java
  • [poj1797]Heavy Transportation<最大生成树prim&kruskal>

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

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

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

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

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

    prim

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdlib>
     6 #include<cstring>
     7 #include<queue>
     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:
    %d
    
    ",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<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<queue>
     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:
    %d
    
    ",k,ans);break;
    68             }
    69         }
    70     }
    71 }
    View Code

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

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

     

  • 相关阅读:
    最新Navicat Premium12 破解方法,亲测可用
    (转)Navicat_12安装与破解激活,注册机亲测可用
    使用ApiPost模拟发送get、post、delete、put等http请求
    模拟POST、Get 请求的工具----APIpost(中文版POSTMAN)
    推荐一款接口文档生成工具,apipost,好用
    作为后端开发者,如何更优雅、便捷的生成接口文档?
    使用apipost调试api接口并快速生成接口文档的一些小技巧,比postman更好用
    中文版postman——apipost,不试一下,你就不知道它有多香
    ApiPost如何在预执行脚本里添加请求参数?
    ApiPost的预执行脚本和后执行脚本
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7785558.html
Copyright © 2011-2022 走看看