zoukankan      html  css  js  c++  java
  • C++常见STL介绍

    栈 :FILO

    栈(stack)又名堆栈,它是一种线性表,是一个后进先出的数据结构。

    使用时须加上头文件:#include<stack>

    允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。

    stack的基本操作有:

    • l 入栈:如s.push(x);
    • l 出栈:如s.pop()。注意出栈操作就是删除栈顶元素;
    • l 访问栈顶:如s.top();
    • l 判断栈空:如s.empty()。当栈空时返回true;
    • l 访问栈中的元素个数。如s.size();

    栈代码示例: 

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<stack> //栈的头文件
      using namespace std;  
    int main ()
    {
     stack<int> s1;   //定义整型栈对象 
     stack<string>s2; //    定义字符型栈对象 
     
     s1.push(2);   // 入栈2,就是插入数据2
     s1.push(168); //入栈168
     s1.push(888);//入栈888,现在栈中元素有{888,168,2} 
     
     cout<<s1.top()<<endl; //访问栈顶元素,输出888
     cout<<s1.size()<<endl; //访问栈中元素个数,输出3
     
     s1.pop();        //出栈,出栈的元素是888
     s1.push(233);   // 入栈233,现在栈中元素应该是{233,168,2}
     
     int a=s1.size();
     for(int i=1;i<=a;i++)
      {
         s1.pop();
         if(s1.empty())   cout<<"空栈"; 
         //如果是空栈(s1.empty()返回true) ,输出空栈 
      } 
          return 0;
    }
    View Code

     

    队列

    1、队列和优先队列的头文件都是<queue>

    2、队列(FIFO):先进先出的数据结构  

    3、queue<int>p; 定义一个变量名为p的队列    

    4 、入队: p.push(x)   将x从队列p最后面插入                 

         出队: p.pop()     弹出(删除)p队列的第一个元素,注意并不会返回被弹出的元素的值             

    访问队首元素:     p.front()   访问最早被压入队列的元素,即队首

    访问队尾元素:     p.back()   访问最晚被压入队列的元素 ,即队尾

    判断队列空:       p.empty()  当队列为空时,返回true

    访问队列元素个数: p.size()   访问队列中元素的个数

    清空队列:         可以p.pop()依次弹出(删除),p.clear()方法不行,是错误的 

    队列示例代码: 

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<queue> //队列和优先队列的头文件 
        using namespace std;
        int h[10]; 
    int main()
    {
        queue<int>p;//声明一个普通队列,普通队列先进先出
        int i,n;
        cin>>n;
        for(i=1;i<=n;i++)
        {
        cin>>h[i];     //输入n个整数 
        p.push(h[i]);  //把输入的数依次压入队列p     
        cout<<p.back()<<" ";  
        //back()总是访问队列的最后一个元素(最后进的元素)
         }   
        cout<<endl<<endl;    
        //队列 示例 
        for(i=1;i<=n;i++)
        {
            cout<<p.front()<<" ";  //front()总是访问队列的第一个元素 (最先进的元素),
            p.pop();             // 将其弹出 ,注意pop()总是弹出队列中的第一个元素 
            
            if(p.empty())   cout<<endl<<"空的队列"; 
            //p.empty()为true时队列为空。 
        }    
        return 0;
    View Code

    动态数组vector:

    C++的STL动态数组使用<vector>头文件

    vector的基本操作有:

    • l 构造vector: vector<T> vec。其中T是数据类型,可以是int、double等。
    • l 插入x元素:  vec.push_back(x)
    • l 获取动态数组大小:vec.size()
    • l 访问动态数组元素:vec[i],和数组一样操作
    • l 修改动态数组元素:比如vec[1]=233,和数组一样操作
    • l 清空动态数组:vec.clear()

    示例代码: 

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<vector> //动态数组头文件 
        using namespace std;
    int main()
    {
        vector<int> vec;   //声明一个int类型的动态数组vec,注意现在动态数组是空的 
        vec.push_back(3);  //通过push_back()方法在动态数组最后面插入一个新的元素3 
        vec.push_back(2);  //...................................................2
        vec.push_back(1);  //...................................................1
        vec.push_back(10); //...................................................10
        for(int i=0;i<vec.size();i++) //vec.size()是获得动态数组vec的长度 
        {
         cout<<vec[i]<<endl;
        }
        vec[0]=10; //修改元素的值,跟正常数组没区别 ,注意第一个元素下标也是0 
        vec[1]=9; 
        vec[2]=8; 
        vec[3]=7;
        cout<<endl; 
        for(int i=0;i<vec.size();++i) //vec.size()是获得动态数组vec的长度 
        {
            cout<<vec[i]<<endl;
        }    
        cout<<endl<<"sort排序后"<<endl; 
        sort(vec.begin(),vec.end()); 
        for(int i=0;i<vec.size();++i)  //vec.size()是获得动态数组vec的长度 
        {
            cout<<vec[i]<<endl;
        }
        cout<<endl;
        vec.clear(); //清空动态数组
        cout<<vec.size();    
        return 0;
    }
    View Code

    快速排序sort

    C++中排序函数sort,在头文件<algorithm>中

    Sort函数有三个参数:

    (1)第一个是要排序的数组的起始下标。

    (2)第二个是要排序的数组的结束下标

    (3)第三个参数是排序的方法,可以是从大到小也可是从小到大,      

    Sortt函数的第三个参数可以用这样的语句告诉程序你所采用的排序原则

    • less<数据类型>()      从小到大排序  如:sort(a,a+n,less<int>())
    • greater<数据类型>()  从大到小排序   如:sort(a,a+n,greater<int>())

    还可以不写第三个参数,此时默认的排序方法是从小到大排序。如:sort(a,a+n)     

    sort可以对任何线性数据排序(比如数组,vector...) 

    sort除了能对int、double等基础数据类型排序以外,

    还能对自定义数据类型进行排序,比如结构体类型。请看后面的示例。 

    示例代码如下: 

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<vector> 
     using namespace std;
     int  a[10]={9,6,3,8,5,2,7,4,1,0},n=9; 
     
     vector<int> v;//定义一个动态数组v 
     
     struct PPtest//定义一个结构体 
     {
         int x,y;
     }p[4]={{1,2},{1,0},{2,1},{0,1}} ;
     
     //现在我们想对P[4]按照x值从小到大进行排序。
     //我们定义一个比较函数int cmp(PPtest a,PPtest b)
     //并把这个函数作为参数传递给sort
     int cmp(PPtest a,PPtest b) //自定义数据类型排序
     {
         if(a.x==b.x) return a.y<b.y; //如果x值相等,就按照y的值从大到小排序 
         return a.x<b.x; // 按照x的值从大到小排序 
     } 
     
    int main()
     {
      for(int i=0;i<=n;i++)    
      cout<<a[i]<<" "; //数组a排序前 
      cout<<endl; 
      
      sort(a,a+n); //也可写成sort(a+0,a+n),表示对数组a的下标区间(0,n)进行排序
      //默认从小到大排序,排序区间是(a+0,a+10)
      //下标0 ,其实也可以这样写 sort(a,a+n,less<int>())
      
      for(int i=0;i<=n;i++)    
      cout<<a[i]<<" ";//数组a排序后 
      cout<<endl; 
      
      sort(a,a+n,greater<int>());
      //加入第三个参数greater<int>()后 ,实现从大到小排序。
      for(int i=0;i<=n;i++)    
      cout<<a[i]<<" ";//数组a排序后 
      cout<<endl;  
         
      sort(p,p+4,cmp);//自定义排序,按照p.x的值从大到小排序
       for(int i=0;i<=3;i++)    
       cout<<p[i].x<<" "<<p[i].y<<endl;//排序后的输出为 {0,1},{1,2},{1,0},{2,1}
       cout<<endl;  
       
       v.push_back(5);//动态数据测试
        v.push_back(8); 
         v.push_back(6); 
          v.push_back(3); 
          sort(v.begin(),v.end());   //对动态数组v[ ]进行排序
       
      for(int i=0;i<=v.size()-1;i++)    
      cout<<v[i]<<" ";//动态数组排序后 
      cout<<endl;  
       
       return 0;
     }
    View Code

    优先队列: 

    l 优先队列的头文件是<queue>

    l 优先队列: 先进的并不一定先出,先出的是最大(或者最小)的数值

    l 从严格意义上来说:优先队列并不是队列,因为它并不遵循队列的FIFO(先进先出的原则)。

    l 优先队列的时间复杂度为O(logn)。

     

    优先队列可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序

    每次的push和pop操作,队列都会动态的调整。以达到我们预期的方式来存储。

    (比如说从小到大或从大到小)

    例如:我们常用的操作就是对数据排序,优先队列默认的是数据大的优先级高

    所以我们无论按照什么顺序push一堆数,最终在优先队列里总是top出最大的元素。 

     

    1、priority_queue <int> q; 定义一个变量名为q的优先队列 ,队内元素优先级是默认从大到小 

    2、priority_queue <int,vector<int>, greater<int> >q;

       定义一个变量名为q的优先队列 ,队内元素优先级是从小到大 (感觉跟sort相似?) 

    3、自定义优先级:priority_queue<int>,vector<int>,cmp>q;

      第一个参数是队列类型,第二个参数为容器类型。第三个参数为比较函数。(又跟sort相似?)

      cmp为比较函数 。请看模板:在最后面。(比sort复杂一点,有重载运算什么之类的)目前可以不研究  

    • l 入队: q.push(x)   从队列q中加入x元素,x自己会在优先队列中找到自己的位置(从大到小或从小到大)               
    • l 出队: q.pop()     弹出(删除)q队列的最大或最小的一个元素,注意并不会返回被弹出的元素的值            
    • l 访问队首元素:    q.top()   访问队首(最大或最小)的元素,不是最早被压入队列的元素
    • l 访问队尾元素:    ........     优先队列没这个方法 
    • l 判断队列空:      q.empty()   当优先队列为空时,返回true 
    • l 访问队列元素个数:q.size()   访问优先队列中元素的个数 
    • l 清空队列:        可以q.pop()依次弹出(删除),q.clear()方法不行,是错误的  

    示例代码一: 

    #include<iostream>
    #include<cstdio>
    #include<queue> //队列和优先队列的头文件 
        using namespace std;
        
    int main()
    {
        priority_queue<int>q;
        //声明一个优先队列 ,注意:优先队列的元素排序默认是从大到小(int)
         
        priority_queue <int, vector<int>, greater<int> >q1;
        //从小到大,注意的是greater<int> >,两个>之间一定有要空格。
            
        int i,n;
        cin>>n;        
        for(i=1;i<=n;i++)
        {
         cin>>h[i];     //输入n个整数 
         q.push(h[i]);  //把输入的数依次加入到优先队列q,动态调整 
         q1.push(h[i]); //把输入的数依次加入到优先队列q1,动态调整     
        }        
    cout<<endl<<endl;
            
        //优先队列从大到小(默认) 
        for(i=1;i<=n;i++)
        {
            cout<<q.top()<<" "; //top()总是访问队首元素(最大), 
            q.pop();
       // 将其弹出 ,注意pop()总是弹出优先队列中优先级最高的元素 (最大) 
            if(q.empty())   cout<<endl<<"队列已为空"; 
        }
        cout<<endl<<endl;
        
        //优先队列从小到大  
        for(i=1;i<=n;i++)
        {
            cout<<q1.top()<<" "; //top()总是访问队首元素(最小), 
            q1.pop();
       //将其弹出 ,注意pop()总是弹出优先队列中优先级最高的元素 (最小) 
            if(q1.empty())   cout<<endl<<"队列已为空"; 
        }
        cout<<endl<<endl;
    
        return 0;
    }
    View Code

    示例代码二:自定义数据类型

    //下面介绍自定义数据类型优先级的操作:
    #include <iostream> 
    #include <cstdio> 
    #include <queue>  
    using namespace std;  
    int n; 
    struct Node//跟sort自定义有点相同,这里分为两个结构体来写,后面还有个cmp, 
    {
    int x;
    int y;
    }dis[10];
    
    struct cmp//Node优先级规则 
    {
        int operator()(Node a,Node b)//注意写法,跟sort不同 ,照着写,我也不明白operator
        {
            return a.x>b.x;//小的优先级高 , 一定要记住,跟sort相反
        } 
    };
    
    //----------------------------------------------------------------- 
    struct cmp1  //结构体优先级规则 
    {  
         bool operator ()(int x, int y) //注意写法,跟sort不同 ,照着写,我也不明白operator
        {  
            return x > y;//小的优先级高 , 一定要记住,跟sort相反 
        }  
    };  
       
    priority_queue<Node,vector<Node>,cmp> d; //自定义结构体优先级   
    priority_queue<int>q1;  //默认,大的优先级高 
    priority_queue<int, vector<int>, cmp1>q2; //小的优先级高 
    //priority_queue <int, vector<int>, greater<int> >q2;  //也是小的优先级高,可以替代上面。
     
    int main()  
    {  
        int i=0;  
        cin>>n;     
        for(int i=0;i<n;i++)  //请输入数据3组,{1,2},{3,1},{2,5}用来测试 
            {  
              cin>>dis[i].x>>dis[i].y;            
              d.push(dis[i]);  //插入数据 
            }  
            cout << endl;          
            while(!d.empty())  //逐步输出优先级大的 
            {  
                cout<<d.top().x <<" "<<d.top().y<<endl;  
                d.pop();  
            }  
            cout << endl;  
    for(int i=0;i<n;i++)  //请输入测试数据 3个,依次是3 7 1  
        {
          int b=0;
          cin>>b;
          q1.push(b);//从q1 队列 插入b 
          q2.push(b);     
        }
        cout<<"q1优先队列"<<endl;
         while(!q1.empty()) //访问q1队顶元素并输出队顶元素 
            {  
                cout<<q1.top() <<endl;  
                q1.pop();  
            }  
        cout << endl; 
        
        cout<<"q2优先队列"<<endl;
         while(!q2.empty()) //访问q1队顶元素并输出队顶元素 
            {  
                cout<<q2.top() <<endl;  
                q2.pop();  
            }  
        cout << endl; 
        return 0;  
    }  
    
    
     /*
    第一组
    3
    1 2
    3 1
    2 5
    第二组:
    3
    7
    1 
    */
    View Code

     

    集合set

    c++ set集合 参考文章https://www.cnblogs.com/zyxStar/p/4542835.html

    集合是数学中的一个基本概念,通俗地理解,集合是由一些不重复的数据组成的。

    比如{1,2,3}就是一个有1,2,3三个元素的集合。

    c++的STL支持集合的高效插入、删除和查询操作,其时间复杂度都是O(logn)。

    如果用数组,虽然插入的时间复杂度是O(1),但是删除和查询都是O(n),时间效率低。

    c++ set的基本操作:

    • l #include<set>//集合头文件
    • l 定义一个集合s: 比如set<int> s;定义一个整型集合s
    • l 返回set集合s中的第一个元素:      s.begin()
    • l 返回set集合s中的最后一个元素:    s.end()
    • l 查找set集合s中的指定元素的个数:  s.count(30),查找元素30有多少个?
    • l 查找set集合s中的指定元素:        s.find(20),查找指定元素20
    • l 删除set集合s中的所有元素:        s.clear()
    • l 判断set集合s是否为空:           s.empty()  为空时返回true
    • l 从set集合s中插入一个元素:       s.insert()
    • l 从set集合s中删除一个元素:       s.erase()
    • l 返回set集合s中元素的个数:       s.size()

    示例代码:  

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<set>//集合头文件
    using namespace std;
    int main()
    {
    set<int> s; // 声明一个整型s集合,初始是空的            
    s.insert(20); //{2} 用insert()方法向集合中插入一个新的元素。                        
    s.insert(10); //{1,2} 插入元素1后集合会自动有序。
    s.insert(30); //{1,2,3},每次插入元素后集合都会自动有序 
    s.insert(10); //{1,2,3}第二次插入1,重复元素,不会插入 
    
    //c++通过迭代器::iterator可以访问集合中的每个元素,可以不懂,记住用法就行了
    set<int>::iterator it;//遍历之前先定义一个(::iterator)迭代器it 
    for(it = s.begin(); it != s.end(); it++)//遍历集合中的元素 
    {
        cout<<(*it)<<" ";//实际上it就是个指针变量。*it是 获取it 指想某个变量的值。     
     } 
    cout<<endl;
    s.erase(30);//{1,2}  删除指定元素 30
    cout<<endl<<"删除30以后"<<endl; 
    
    for(it = s.begin();it != s.end();++it)
        cout<<(*it)<<" ";//实际上it就是个指针变量。*it是 获取it 指想某个变量的值。 
    cout<<endl<<endl;
    
    cout<<"查找指定元素20"<<endl; //遍历查找元素20 
    it = s.find(20);    //查找键指定元素20 
      if (it != s.end())    //找到
         cout << *it << endl;      
           else            //未找到
             cout << "未找到"<<endl;
      
    cout<<endl<<"查找有多少个30这样的元素"<<endl;// 
    if(s.count(30))    //可以用count()方法查找集合中的指定元素的个数。 
       cout<<s.count(30)<<endl; 
        else cout<<"没有30这个元素"<<endl<<endl;
    
    cout<<s.size()<<"  "<<s.max_size()<<endl;
    //输出集合中所有元素的个数及集合可以容纳最大的元素上限 
    
    s.clear();//清空集合 
    cout<<"清空集合后,集合中的元素为"<<" "; 
    cout<<s.size()<<endl;
        
        return 0;
     } 
    View Code

    C++中的STL中map用法详解 映射

    参考文章:https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html

                    注意:文章中像数组一样遍历好像不行。

                   https://www.cnblogs.com/qigaohua/p/5803629.html

     

           map映射是指两个集合之间的元素的相互对应关系。通俗地说,就是一个元素对应另外一个元素。

          众所周知,在定义数组时(如int array[100]),其实是定义了一个从int型到int型的映射,比如array[1]=28、array[3]=66就分别是将1映射到28、将3映射到66。一个double型数组则是将int映射到double型,例如db[0]=6.12,db[1]=10.02。但是,无论是什么类型,它总是将int型映射到其他类型。这似乎表现出一个弊端:当需要以其他类型作为关键字来映射时,会显得很不方便。例如有一本字典,上面提供了很多字符串和对应的页码,如果要用数组来表示“字符串-->页码”这样的对应关系,就会感觉不太好操作。这时,就可以用到map,因为map可以将任何基本类型映射到任何基本类型,也就可以建立string型到int型的映射。

    比如有一个姓名集合{"Tom","Jone","Mary"},班级集合{1,2}。

    姓名与班级之间可以有如下的映射关系:

    class("Tom")=1, class("Jone")=2, class("Mary")=1。

    我们称其中的姓名集合为 关键字集合(key),班级集合为 值集合 (value)。 

    map的基本操作函数(常用):

     begin()    返回指向map头部的迭代器          end()   返回指向map末尾的迭代器

     rbegin()    返回指向map尾部的反向迭代器   rend()   返回指向map头部的反向迭代器

     clear()    删除所有元素                              empty() 如果map为空则返回true

     count()    返回指定元素是否出现            find()  查找一个指定元素

     insert()    插入元素                                 erase() 删除一个元素

     size()     返回map中元素的个数           max_size()   返回可以容纳的最大元素个数

     swap()   交换两个map,使用方法m1.swap(map2) ;m1和m2两个映射交换,而不是映射中的两个元素交换 

    代码示例:

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<map>//集合头文件
    using namespace std;
     
    int main ()
    {
    //数据的插入--第一种:用insert函数插入pair数据
    map <int,string> mapStudent;//{}初始是空映射 
    mapStudent.insert(pair<int, string>(3, "student_three"));
    mapStudent.insert(pair<int, string>(1, "student_one"));
    //插入新的映射,映射会根据关键字key自动升序排序
    mapStudent.insert(pair<int, string>(2, "student_two"));
    mapStudent.insert(pair<int, string>(2, "student_2"));
    //如果关键字key已经有了,就是无效插入,就算值value不同。
    //但是如果是数组的方式插入,就会覆盖原来的
     
     
    //遍历map,第一种方法,使用前向迭代器 ,就是顺序遍历
    map<int, string>::iterator iter;//定义一个前向迭代器iter,不明白没关系,记住使用方法
                                 //map<元素类型,元素类型>::iterator  变量
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
    cout<<iter->first<<" "<<iter->second<<endl; //first对应map关键字key,second对应map的值value
     
    cout<<endl<<"映射mapStudeng的大小为:"<<mapStudent.size()<<endl<<endl;
    //查询映射的大小
     
    //数据的插入--第二种:像数组一样使用
    map <string,int> DICT;//{}
    DICT["Tom"]=1;//还可以像访问数组一样访问映射。 
    DICT["Jone"]=2;
    DICT["Mary"]=1;
    DICT["Tom"]=2;//就算已有关键字Tom,也会完全覆盖原有的映射 
    DICT["Test"];//如果这个映射不存在,自动建立一个新映射,默认Key值0
     
    //输出测试
    cout<<"测试映射的值是什么"<<endl;
    cout<<DICT["Mary"]<<endl;//输出Mary的值1
    cout<<DICT["Test"]<<endl;//输出Test的值0
    cout<<endl<<endl;
     
    //遍历map,第二种方法,使用反向迭代器 ,就是反向遍历
    map<string,int>::reverse_iterator it; //map<元素类型,元素类型>::reverse_iterator  变量 
     
    for(it = DICT.rbegin();it != DICT.rend();++it)
    //反向遍历map,注意不是begin()和end(),而是rbegin()和rend()
    cout<<it->first<<"在班级  "<<it->second<<endl;
    //first对应map关键字key,second对应map的值value
     
    //删除映射,两种方法
    //1、可以用关键字删除,比如m.erase(1),
    //2、也可以成片的删除,如m.erase(m.begin(),m.end());
    DICT.erase("Tom");//单独删除Tom关键字
    cout<<endl<<"删除后Tom映射不见了"<<endl;
    for(it = DICT.rbegin();it != DICT.rend();++it)
    //反向遍历map,注意不是begin()和end(),而是rbegin()和rend()
    cout<<it->first<<"在班级  "<<it->second<<endl;
    //first对应map关键字key,second对应map的值value
     
    cout<<endl<<"全部删除所有映射"<<endl;
    DICT.erase(DICT.begin(),DICT.end()) ;//成片删除 跟DICT.clear效果一样DICT.clear();  
    cout<<DICT.size()<<endl;
     
    /*查找并获取map中的元素(包括判定这个关键字是否在map中出现):
    有两种:1、用m.count() 用2、m.find()
    第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,
    count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了 */
     
    cout<<endl<<"count查找...."<<endl;
    map <string,int> m;//{}
    m["Tom"]=2;
    m["Jone"]=5;
    m["Mary"]=3;
    if(m.count("Tom"))//如果Tom出现 
    cout<<m.count("Tom")<<endl;//返回1 
     
    /*第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,
    它返回数据所在位置的迭代器,如果map中没有要查找的数据,
    它返回的迭代器等于end函数返回的迭代器 */
    map<string,int>::iterator TEST;//定义一个迭代器TEST
     
    cout<<endl<<"前向遍历"<<endl;
    for(TEST=m.begin();TEST!=m.end();TEST++)//前向遍历 
      cout<<TEST->first<<"  "<<TEST->second<<endl;
      
    cout<<endl<<"find()查找...."<<endl;
    TEST=m.find("Tom");
    if(TEST!=m.end())//判断是否找到Tom,记住判断方法
       {
          cout<<"找到了,他的值是 "<<TEST->second<<endl;
          m.erase(TEST); //测试用,删除Tom 
       }
             else  cout<<"没找到"<<endl;
             
    //排序 map中的sort问题 ,略.................
     
    return 0;
    }
    View Code
  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/wozaixuexi/p/8330594.html
Copyright © 2011-2022 走看看