老刘说让我写个图论的总结(一个月前),当时因为在写dp所以推了,今日看尧神在写,不妨补上;
一些模板;
//图论的一些模板;
总结于 2017 3 28,尧神搞完了图论,我跟着写一波总结
/*一个概念;欧拉路
欧拉路也就是一笔画成问题,欧拉路的必要判定条件是每个点的入度为偶数,或者是只有两个点是奇数,
当满足条件2时,这两个点必定一个是起点一个是终点;
/*/
最短路的求法
{
1.
//floyed;
for(int i=1;i<=k;i++)
for(int j=1;j<=k;j++)
for(int u=1;u<=k;u++)
{
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][u]);
}
//(500数据量的求法,基本没用;)
//堆优化的dijkstra
#include<iostream>
#include<string>
#include<algorithm>
#include<queue>
typedef pair <int,int> pii;
viod dijkstra(int s){
priority_queue<pii>q;
memset(dis,10,sizeof(dis));
meset(vis,0,sizeof(vis));
d[s]=0;
q.push(make_pair(0,s));
while(!q.empty){
pii tmp=q.top();
q.pop();
int x=tmp.second;
if(vis[x])continue;
vis[x]=1;
for(int i=lin[x];i;i=e[i].next){
if(dis[e[i].y]>dis[x]+e[i].v){
dis[e[i].y]=dis[x]+e[i].v;
q.push(make_pair(e[i].y,x));
}
}
}
}
//判断是否有负环;
//bellman-ford;
//边表存贮;
int bellman-ford(int st){
memset(dis,10,sizeof(dis);
dis[st]=0;
int num=0;
for(int i=1;i<=n;i++){
for(int i=1;i<=sum;i++){
if(dis[a[i].x]+a[i].v<dis[a[i].y])
dis[a[i].y]=dis[a[i].x]+a[i].v,num=1;
if(num==0)return 0;//无负环;
}
return 1;//有负环
}
}
//spfa;
void spfa(int st)
{
memset(dis,10,sizeof(dis));
memset(vis,0,sizeof(vis));
int head=0,tail=1;
while(head<tail)
{
head++;
int x=q[head];
vis[x]=0;
for(int i=lin[q[head]];i;i=e[i].next)
{
int y=e[i].y;
if(dis[x]+e[i].v<dis[y])
{
dis[y]=e[i].v+dis[x];
if(vis[y]==0)
{
vis[y]=1;
q[++tail]=y;
vis[y]=0;
}
}
}
}
}
//最小生成树_边表
//kruskal
int getfather(int k)
{
if(k==father[k])return father[k];
father[k]=getfather(father[k]);
return father[k];
}
void merge(int x,int y);
{
x=getfather(x);
y=getfather(y);
fahter[x]=father[y];
}
int judge(int x,int y)//判断;
{
father[x]=getfather(x);
father[y]=getfather(y);
if(father[x]==father[y])return 1;
return 0;
}
int krskal(int x)
{
for(int i=1;i<=len;i++)
{
int x=e[i].x;
int y=e[i].y;
if(x!=y)
{
merge(x,y);
}
}
}
//topsort 据说是为了确定搜索顺序
void topsort()
{
for(int i=1;i<=n;i++)
{
if(vis[i]==0)
q[++tail]=i;
}
while(head<tail)
{
head++;
int x=q[head];
for(int i=lin[x];i;i=e[i].next)
{
int y=[i].y;
vis[y]--;
if(vis[y]==0)q[++tail]=y;
}
}
}//q 里存的即是topsort序列;
//注意, topsort的序列并不是唯一的,枚举所有的排序情况需要用dfs来存;
// 割边割点与强连通分量;
/* int dfn[10000000],low[10000000];
割点; 所谓割点,即去掉此点后图不连通,那么只需求一下某个点是否能回到比他早的路即可;
*/
trajan(int x,int father)
{
dfn[x]=low[x]=++num;
int son=0;
for(int i=lin[x];i;i=e[i].next)
{
int y=e[i].y;
if(y!=father)
{
if(!dfn[y])
{
trajan(y,x);
if(low[y]<low[x]);
low[x]=low[y],son++;
}
if(dfn[y]<low[x])low[x]=dfn[y],son++;
}
}
if(son==1&&father!=-1||son>=2)
f[x]=1;
}
// 割边;去掉该边后图不连通;
trajan(int x,int fatherlen)
{
dfn[x]=low[x]=++num;
for(int i=lin[x];i;i=e[i].next)
{
int y=e[i].y;
if(i!=fatherlen)
{
if(!dfn[y])
{
trajan(y,x);
if(low[y]<low[x]);
low[x]=low[y];
}
if(dfn[y]<low[x])low[x]=dfn[y];
}
}
if(dfn[x]==low[x])f[fatherlen]=;
}
//强连通分量;
//int tot=0;
//int tnt[10000000];
//int struck[1000000];
//int top=0;
//int bel[10000000];
trajan(int x,int father)
{
dfn[x]=low[x]=++num;
struck[++]
int son=0;
for(int i=lin[x];i;i=e[i].next)
{
int y=e[i].y;
if(!dfn[y])
{
trajan(y,x);
if(low[y]<low[x]);
low[x]=low[y];
}
if(dfn[y]<low[x])low[x]=dfn[y];
}
if(dfn[x]==low[x])
{
tot++;int k;
while(k!=x)
{
k=struck[top--];
tnt[tot]++;
bel[k]=tot;
}
}
}
///*/*/*/*/*/*/*/*/*/*/*/*/*终于写完了(累.....)*/*/*/*/*/*/*/*/*/*/*/*/*/*/*
//*/*/*/*/*/*/*/*/*/*/*/*/*/*好像还有个什么差分约束,过两天再弄吧*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
}