• P1111 修复公路


    题目背景

    AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。

    题目描述

    给出A地区的村庄数NN,和公路数MM,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)

    输入输出格式

    输入格式:

    11行两个正整数N,MN,M

    下面MM行,每行33个正整数x, y, tx,y,t,告诉你这条公路连着x,yx,y两个村庄,在时间t时能修复完成这条公路。

    输出格式:

    如果全部公路修复完毕仍然存在两个村庄无法通车,则输出-11,否则输出最早什么时候任意两个村庄能够通车。

    输入输出样例

    输入样例#1: 复制

    4 4
    1 2 6
    1 3 4
    1 4 5
    4 2 3

    输出样例#1: 复制

    5

    很明显是最大生成树问题 只不过把权值和变成了最大权值 当dis=inf 时 说明有些点没有遍历到


    prim

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define LL long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define N 1000+1
    int mp[N][N];
    int dis[N];
    int vis[N];
    int n;
    int prim(void)
    {
        rep(i,1,n)
        dis[i]=mp[1][i],vis[i]=0;
        dis[1]=0;
        rep(i,1,n)
        {
            int u,minn=inf;
            rep(j,1,n)
            if(!vis[j]&&dis[j]<minn)
                minn=dis[u=j];
            vis[u]=1;
            rep(j,1,n)
            if(!vis[j]&&dis[j]>mp[u][j])
                dis[j]=mp[u][j];
        }
        int ans=0;
        rep(i,1,n)
        ans=max(ans,dis[i]);
        return ans;
    }
    
    int main()
    {
        int q;
        RII(n,q);
        rep(i,1,n)
        rep(j,1,n)
        mp[i][j]=inf;
        while(q--)
        {
            int a,b,c;
            RIII(a,b,c);
    
            mp[a][b]=mp[b][a]=c;
        }
        int ok=1;
        int ans=prim();
    
        if(ans!=inf)
           printf("%d
    ",ans);
        else
            printf("-1");
    }
    View Code

    kruskal

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define LL long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define N 1000+5
    struct node
    {
        int s,e,v;
    }s[100005];
    int f[N];
    int n,m;
    int find1(int x)
    {
      return f[x]==x?x:find1(f[x]);
    }
    bool cmp(node a,node b)
    {
        return a.v<b.v;
    }
    int kruskal()
    {
        int a,b,x=1;//一开始一定要是1
        int ans=0;
        sort(s+1,s+1+m,cmp);
        rep(i,1,m)
        {
            int a=find1(s[i].s);
            int b=find1(s[i].e);
            if(a==b)continue;
            ans=max(ans,s[i].v);
            f[a]=b;
            x++;
            if(x==n)return ans;//遍历了所有的点 是时候退出了
        }
        if(x!=n)return -1;//说明没有最小生成树
        else return ans;
    }
    
    int main()
    {
        RII(n,m);
        rep(i,1,n)
        f[i]=i;
        rep(i,1,m)
        RIII(s[i].s,s[i].e,s[i].v);
        printf("%d
    ",kruskal());
    }
    View Code




  • 相关阅读:
    万网中备份数据操作
    《C++ Primer Plus》学习笔记3
    Redhat Linux 下安装Oracle 11g R2
    Android-shareSDK
    jQuery的AJax异步訪问
    swift语言初见
    Num 36 : ZOJ 2100 [ 深度优先搜索算法 ] [ 回溯 ]
    一个点的经度和纬度,以这个点为圆心,1000米为半径,最大的经度和纬度,最小的经度和纬度
    [Swift]LeetCode227. 基本计算器 II | Basic Calculator II
    [Swift]LeetCode225. 用队列实现栈 | Implement Stack using Queues
  • 原文地址:https://www.cnblogs.com/bxd123/p/10561714.html
Copyright © 2020-2023  润新知