zoukankan      html  css  js  c++  java
  • 第三节暑期信息奥赛课——图论

    2019-07-08 16:02:00

    第三节暑期信息奥赛课——图论

    绪言

    图论这东西,纠缠我很久啦!我接触的第一道图论题是2017普及组D1T3 洛谷P3956 棋盘(dijkstra算法)

    当时用暴力法,整了个不到50分,但是还是不会这个算法。

    图论乃是NOIP的重点之一!


     最短路径问题


    ----Floyd

    时间复杂度O(n^3)

    只有五行!!!死也要给我背下来!!!

    #include<iostream>
    //#include<cstring>
    using namespace std;
    int main(){
        int num,way;
        cin>>num>>way;
        int sz[num+1][num+1];
        int tx,ty,tz;
        for(int n=1;n<=num;n++)
        for(int m=1;m<=num;m++)
            sz[n][m]=0xFFF;
        //memset(sz,0x3F,sizeof(sz);
        for(int n=1;n<=way;n++)
        {
            cin>>tx>>ty>>tz;
            sz[tx][ty]=min(sz[tx][ty],tz);//陷阱一:可能有重复输入两点距离 
        }
        
        for(int i=1;i<=num;i++)
            sz[i][i]=0;//自己到自己的距离是0 
        //核心代码 
        for(int k=1;k<=num;k++){//k一定是在最外层,在动规中是状态 
            for(int i=1;i<=num;i++)
            for(int j=1;j<=num;j++){
            if(sz[i][j] > sz[i][k]+sz[k][j]);//寻找桥梁点k,会使得i to k&k to j比i to j更短 
                sz[i][j] = sz[i][k]+sz[k][j];
            }
        }
        
        for(int i=0;i<num;i++){
            for(int j=0;j<num;j++)
                cout<<sz[i][j]<<" ";
            cout<<endl;
            }
        return 0;
    } 

    ----Dijkstra

    基础版的O(n^2),代码稍长

    可优化

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int MAXN=0x3F,inf=0x3F3F3F;
    int num,way,minNum,minIndex;
    int sz[MAXN][MAXN];
    int dis[MAXN];
    bool vis[MAXN];
    void dij(int s){
        memset(dis,1,sizeof(dis));
        memset(vis,1,sizeof(vis));
        for(int p=1;p<=num;p++)
            dis[p]=sz[s][p];
        vis[s]=1;
        
        for(int j=1;j<=num;j++){
            int minIndex=1,minNum=inf+1;
            for(int i=1;i<=num;i++)
                if(vis[i]==1 && dis[i]<minNum){
                    minNum=dis[i];
                    minIndex=i;
                }
        } 
        
        vis[minIndex]=1;
        for(int i=1;i<=num;i++)
            if(vis[i]==1 && dis[i]>dis[minIndex]+sz[minNum][i]){
                dis[i]==dis[minIndex]+sz[minNum][i];
            }
    }
    int main(){
        cin>>num>>way;
        int tx,ty,tz;
        //初始化 
        for(int n=1;n<=num;n++)
        for(int m=1;m<=num;m++)
            sz[n][m]=MAXN;
        //msmset(sz,0x3F,sizeof(sz);
        for(int n=1;n<=way;n++)
        {
            cin>>tx>>ty>>tz;
            sz[tx][ty]=min(sz[tx][ty],tz);//陷阱一:可能有重复输入两点距离 
        }
        dij(1);
        for(int i=1;i<=num;i++){
            for(int j=1;j<=num;j++)
                cout<<sz[i][j]<<" ";
            cout<<endl;
            }
        return 0;
    } 
    /*
    1、把sz[1][j]搬到一个一维数组dis中(起点到其他所有点的距离) 
    2、松弛操作:从dis中找一个没用过,且最小的点
    3、 
    */

    最小生成树问题


    ----kruskal

    要用到并查集哟(^U^)ノ~YO

    #include<iostream>
    using namespace std;
    int n,m;
    const int MAXN=0x3F3F3F;
    int f[MAXN];
    //并查集开始 
    int init(){//初始化 
        for(int i=1;i<=n;i++)
            f[i]=i;
    } 
    
    int getf(int i){
        if(i==f[i]) return i;//没有祖先,或者说就是它自己 
        else return f[i]=getf(f[i]);//有祖先,就把f[i]也变成即将查找到的它的祖先的祖先,状态压缩 
    }
    
    void merge(int a,int b ){
        int x=getf(a);
        int y=getf(b);
        
        if(x!=y) f[x]=f[y];
    }    
    int main(){
        int a,b,c;
        cin>>n>>m;
        init(); //初始化
        for(int i=1;i<=m;i++)
            cin>>a>>f[a];
        
            
        return 0;
    } 
     
    /*
    kruskal算法 
    1、清除所有边
    2、找两点使得距离最短,连线
    3、用并查集判断有没有环(回路)
    4、 
    */ 
    /*
    并查集
    对一个集合进行合并,查找
    1、把一个一维数组sz的值初始化为其下标
    2、若A与B有关系,则sz[A]=B;
    3、若A与C有关系 
    最后,有多少个下标仍是值的数值,就有 
    */ 
    kruskal

    代码的输入有问题,记得修复!


    ----Prim

    (未完待续......)

    以后做到了再说吧。。。

  • 相关阅读:
    Jquery消息提示插件toastr使用详解
    spingboot jar 包启动遇到得坑
    freemarker使用shiro标签(spring boot)
    sping boot 集成shiro
    java 线程安全(初级)
    java GC jvm 内存分布 和新生代,老年代,永久代,(详细)
    java的新生代 老年代 永久代
    windows下rabbitmq(架构师必备神器)集群搭建
    友盟移动开发平台.NET版本SDK
    jstree无限级菜单ajax按需动态加载子节点
  • 原文地址:https://www.cnblogs.com/send-off-a-friend/p/11138181.html
Copyright © 2011-2022 走看看