ACM暑期训练_0808

next_permutation

全排列生成函数

bool _Next_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred)

first,last分别指向其起始和末尾,左闭右开

如果**能生成更大的字典序排列,则返回true**,否则返回false

时间复杂度大概在O(n/2)

int num[4]={1,3,2,4};
sort(num,num+4);
do{
    for(int i=0;i<4;i++) printf("%d%c",num[i],i==3?'\n':' ');
}while(next_permutation(num,num+4));
return 0;

list

list是一个线性双向链表结构
1. 每一个节点都包括一个数据,一个前驱指针和一个后驱指针
2. 存储在非连续的内存空间中,不能进行内部的随机访问,即不支持[ ] 操作符和vector.at()
3. 可以迅速的在任意节点插入或者删除元素
4. 可以在内部任何位置快速地插入或删除,当然也可以在两端进行push 和pop


#include<list>


void PrintIt(string& StringToPoint)
{
cout << StringToPoint << endl;
}


list<string> test;

list<string>::iterator testiterator;

test.push_back("no");
test.push_back("march");
test.push_front("ok");
test.push_front("loleina");
test.push_front("begin");
test.push_back("end");


for (testiterator = test.begin(); testiterator != test.end(); ++testiterator)
{
cout << *testiterator << endl;
}

for_each(test.begin(), test.end(), PrintIt);
 cout << "-------------" << endl;

拓扑排序

  1. 拓扑排序是一个有向无环图的所有顶点的线性序列
  2. 每个顶点出现且只出现一次
  3. 有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说
  4. 一个有向无环图可以有一个或多个拓扑排序序列

常用方法

  1. 从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出
  2. 从图中删除该顶点和所有以它为起点的有向边
  3. 重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<list>
using namespace std;

class Graph
{
    int V;                      //顶点个数
    list<int> *adj;             //用list实现邻接表
    queue<int> q;               //用于保存入度为0的节点编号
    int *indegree;              //入度数组

    public:
        Graph(int V);
        ~Graph();
        void addEdge(int u,int v);
        bool toposort();
};

Graph::Graph(int V)             //构造函数
{
    this->V=V;
    adj=new list<int>[V+1];         //创建V个list,每个list长度不定
    indegree=new int[V+1];          //这里需要+1吧?
    for(int i=0;i<V;i++)
        indegree[i]=0;
}

Graph::~Graph()
{
    delete [] adj;                  //删除很重要
    delete [] indegree;
}

void Graph::addEdge(int u,int v)
{
    adj[u].push_back(v);
    indegree[v]++;
}

bool Graph::toposort()
{
    for(int i=0;i<V;i++)
        if(indegree[i]==0)
            q.push(i);
    int cnt=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();

        printf("%d ",u);
        cnt++;

        list<int>::iterator it;
        for(it=adj[u].begin();it!=adj[u].end();it++)
        {
            if(!(--indegree[*it]))          //删除一个节点后把与他相连的节点入度统统减一
                q.push(*it);                //入度为0重新入队列
        }
    }
    if(cnt<V) return false;                 //没有输出全部顶点,有向图中存在回路
    else return true;
}
int main()
{
    Graph G(6);
    G.addEdge(5, 2);
    G.addEdge(5, 0);
    G.addEdge(4, 0);
    G.addEdge(4, 1);
    G.addEdge(2, 3);
    G.addEdge(3, 1);
    G.toposort();
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值