终于打过平衡树了!我来写写set的小科技。写得不一定完全。
调用和定义
首先
#include<set>
然后就
set<struct_type> name
or
multiset<数据类型> 名字
不需要给set开空间的~~~
进一步了解
实际上set或multiset是个平衡树,只要重定义 < 就可以用来干很多事情。
每一个位置是一个迭代器,就像指针一样,迭代器支持++运算。然后要取值就要用*号,比如我们用一个变量赋给它迭代器的值,即指向。
set<struct_type> s
set<struct_type> :: iterator poto=s.begin()
其中poto前面是定义那种类型的set的迭代器,s.begin()则是查找set开头的迭代器的函数。
然后我们
for(poto=s.begin;poto!=s.end();++poto)
就可以遍历完整个set
s.end()是获取结尾迭代器的函数,结尾迭代器一般指向null
一些操作及注意
厚颜无耻地复制一波WerKeyTom_FTD的操作并添加注解~~~
假设我们定义的多重集叫s。
调用set自带函数用 s.functionname() 类似的语句
begin()返回指向第一个元素的迭代器
clear()清除所有元素
count()返回某个值元素的个数
empty()如果集合为空,返回true
end()返回指向最后一个元素的迭代器
insert()在集合中插入元素
erase()删除集合中的元素 ,注意这里要的参数不是元素,是元素的迭代器,即位置。
lower_bound()返回指向大于(或等于)某值的第一个元素的迭代器
upper_bound()返回大于某个值元素的迭代器 ,注意这两个bound并不是相反的。
size()集合中元素的数目
swap()交换两个集合变量
equal_range()返回集合中与给定值相等的上下限的两个迭代器
find()返回一个指向被查找到元素的迭代器
get_allocator() 返回集合的分配器
key_comp()返回一个用于元素间值比较的函数
max_size()返回集合能容纳的元素的最大限值
rbegin()返回指向集合中最后一个元素的反向迭代器
rend()返回指向集合中第一个元素的反向迭代器
value_comp()返回一个用于比较元素间的值的函数
代码
是打dijkstra带上的set,参考一下
#include<cstdio>
#include<iostream>
#include<set>
using namespace std;
#define fo(i,j,k) for(i=j;i<=k;i++)
const int N=10005,inf=10000007;
struct rec
{
int i,dis;
}dur,tmp;
multiset<rec> b;
int i,j,k,n,dis[N],m,x,y,z,tt,p;
int bc[2*N],c[2*N],first[N],next[2*N],pd[N];
bool operator <(rec a,rec b)
{
return a.dis<b.dis;
}
int cr(int x,int y,int z)
{
tt++;
bc[tt]=y;
c[tt]=z;
next[tt]=first[x];
first[x]=tt;
}
void dij()
{
fo(i,1,n) dis[i]=inf;
pd[1]=1;
dur.i=1;
dis[1]=dur.dis=0;
b.insert(dur);
while (!b.empty())
{
do
{
dur=*b.begin();
b.erase(b.begin());
}while (pd[dur.i]!=1&&!b.empty());
if(pd[dur.i]!=1) break;
for(p=first[dur.i];p;p=next[p])
{
if (dis[bc[p]]>dis[dur.i]+c[p])
{
pd[bc[p]]=1;
dis[bc[p]]=dis[dur.i]+c[p];
tmp.i=bc[p];
tmp.dis=dis[bc[p]];
b.insert(tmp);
}
}
pd[dur.i]=2;
}
return;
}
int main()
{
freopen("dij.in","r",stdin);
scanf("%d%d",&n,&m);
fo(i,1,m)
{
scanf("%d%d%d",&x,&y,&z);
cr(x,y,z);
cr(y,x,z);
}
dij();
if (dis[n]==inf)
printf("-1");
else
printf("%d",dis[n]);
}