图论Word下载.docx

上传人:b****6 文档编号:16932293 上传时间:2022-11-27 格式:DOCX 页数:52 大小:28.67KB
下载 相关 举报
图论Word下载.docx_第1页
第1页 / 共52页
图论Word下载.docx_第2页
第2页 / 共52页
图论Word下载.docx_第3页
第3页 / 共52页
图论Word下载.docx_第4页
第4页 / 共52页
图论Word下载.docx_第5页
第5页 / 共52页
点击查看更多>>
下载资源
资源描述

图论Word下载.docx

《图论Word下载.docx》由会员分享,可在线阅读,更多相关《图论Word下载.docx(52页珍藏版)》请在冰豆网上搜索。

图论Word下载.docx

3、 

问题再次被转化为“至少在缩点树上增加多少条树边,使得这棵树变为一个双连通图”。

若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么至少增加的边数=(这棵树总度数为1的结点数+1)/2

4、若low[v]>

dfn[u],则(u,v)为割边。

但是实际处理时我们并不这样判断,因为有的图上可能有重边,这样不好处理。

我们记录每条边的标号(一条无向边拆成的两条有向边标号相同),记录每个点的父亲到它的边的标号,如果边(u,v)是v的父亲边,就不能用dfn[u]更新low[v]。

这样如果遍历完v的所有子节点后,发现low[v]=dfn[v],说明u的父亲边(u,v)为割边。

voidtarjan(intx)

 

vis[x]=1;

dfn[x]=low[x]=++num;

for(inti=head[x];

i;

i=next[i])

if(!

vis[ver[i]])

 

p[ver[i]]=edge[i];

//记录父亲边

tarjan(ver[i]);

low[x]=min(low[x],low[ver[i]]);

elseif(p[x]!

=edge[i])//不是父亲边才更新

low[x]=min(low[x],dfn[ver[i]]);

if(p[x]&

&

low[x]==dfn[x])f[p[x]]=1;

//是割边

PS:

最大流=最小割

一、

1、邻接矩阵(略)

2、邻接链表

#include<

cstdio>

cstring>

algorithm>

usingnamespacestd;

constintN=102;

structEdgeNode

intto;

//终点

intw;

//权值

EdgeNode*next;

//指向下一条边的指针

EdgeNode()

{

next=NULL;

}

};

structVNode//起点表节点

intfrom;

//起点

EdgeNode*first;

//邻接表头指针

}Adjlist[N];

//整个图的邻接表

voidaddEdge(inta,intb,intwi)

EdgeNode*p=newEdgeNode();

p->

to=b;

w=wi;

next=Adjlist[a].first;

Adjlist[a].first=p;

voidprintEdge(intn)

for(inti=1;

i<

=n;

++i)

for(EdgeNode*k=Adjlist[i].first;

k!

=NULL;

k=k->

next)

printf("

vi=%d,vj=%d,w=%d\n"

i,k->

to,k->

w);

voiddelEdge(intn)//把申请的边的内存空间释放掉,防止超内存

EdgeNode*p=Adjlist[i].first;

EdgeNode*k=NULL;

while(p!

=NULL)

k=p->

next;

deletep;

p=k;

intvis[N];

voiddfs(intu)

vis[u]=1;

for(EdgeNode*k=Adjlist[u].first;

if(!

vis[k->

to])

dfs(k->

to);

voidinit(intn)

Adjlist[i].first=NULL;

memset(vis,0,sizeof(vis));

intmain()

intn,m;

while(scanf("

%d%d"

&

n,&

m)!

=EOF)

init(n);

for(inta,b,i=0;

m;

scanf("

a,&

b);

addEdge(a,b,1);

dfs

(1);

intres=0;

if(vis[i])

res++;

%d\n"

res);

delEdge(n);

return0;

3、链式前向星

constintM=102;

inthead[N];

inttot;

//已申请节点的个数

structEdge

intnext;

}edge[M];

voidaddEdge(intvi,intvj,intwi)

edge[tot].from=vi;

edge[tot].to=vj;

edge[tot].w=wi;

edge[tot].next=head[vi];

head[vi]=tot++;

for(inti=head[u];

i!

=-1;

i=edge[i].next)

vis[edge[i].to])

dfs(edge[i].to);

voidprintEdges(intn)

for(intj=head[i];

j!

j=edge[j].next)

i,edge[j].to,edge[j].w);

voidinit()

tot=0;

memset(head,-1,sizeof(head));

while(scanf("

init();

二、

1、Dijkstra

#include<

iostream>

queue>

#defineMAX0x3f3f3f3f

typedefpair<

int,int>

P;

structnode

intto,cost;

}edge[10000];

intcnt;

intn,start,end;

inthead[5000];

voidadd(intfrom,intto,intcost)

edge[cnt].to=to;

edge[cnt].cost=cost;

edge[cnt].next=head[from];

head[from]=cnt++;

voiddijkstra()

intdis[5000];

inti,v;

priority_queue<

P,vector<

P>

greater<

>

que;

nodee;

Pp;

fill(dis,dis+n,MAX);

dis[start]=0;

que.push(P(0,start));

while(!

que.empty())

p=que.top();

que.pop();

v=p.second;

if(dis[v]<

p.first)

continue;

for(i=head[v];

i!

i=edge[i].next)

e=edge[i];

if(dis[e.to]>

dis[v]+e.cost)

dis[e.to]=dis[v]+e.cost;

que.push(P(dis[e.to],e.to));

dis[end]==MAX?

-1:

dis[end]);

intm,from,to,cost;

while(~scanf("

m))

cnt=0;

while(m--)

%d%d%d"

from,&

to,&

cost);

add(from,to,cost);

add(to,from,cost);

start,&

end);

dijkstra();

2、spfa优化版(一般用于稀疏图)

deque>

constintN=501;

constintNN=100001;

constintinf=0x7fffffff;

intn,nu;

intvis[N],dis[N],num[N];

typedefstructnode

intadj,val;

structnode*next;

nodenode[NN],*p[N];

intSPFA(intstart)

deque<

int>

qu;

intx,i,a,b;

structnode*head[N];

for(i=1;

i++)

vis[i]=0;

num[i]=0;

dis[i]=inf;

head[i]=p[i];

vis[start]=1;

num[start]++;

qu.push_back(start);

qu.empty())

x=qu.front();

qu.pop_front();

vis[x]=0;

head[x]=p[x];

while(head[x])

a=head[x]->

adj;

b=head[x]->

val;

if(dis[a]>

dis[x]+b)

dis[a]=dis[x]+b;

if(!

vis[a])

vis[a]=1;

num[a]++;

if(num[a]>

=n)

return1;

//如果要求一条负环回路上的点只需在这里改改就行

dis[qu.front()])

qu.push_back(a);

else

qu.push_front(a);

head[x]=head[x]->

intt,i,m,w,a,b,c;

%d"

t);

while(t--)

memset(node,0,sizeof(node));

memset(p,0,sizeof(p));

nu=0;

m);

for(i=0;

b,&

c);

node[nu].adj=b;

node[nu].val=c;

node[nu].next=p[a];

p[a]=&

node[nu];

nu++;

node[nu].adj=a;

node[nu].next=p[b];

p[b]=&

if(SPFA

(1))

puts("

YES"

);

dis[n]);

3、第k短路

string>

map>

#defineinf0x7fffffff

constintmaxn=1010;

intd[maxn],head[maxn],head2[maxn],n,m,cnt;

boolvis[maxn];

intto,cost,next;

}edge[100010],edge2[100010];

structnode1

intv,g,f;

//f=g+h

booloperator<

(constnode1&

r)const

if(r.f==f)returnr.g<

g;

returnr.f<

f;

memset(head,-1,sizeofhead);

memset(head2,-1,sizeofhead2);

memset(d,0x3f,sizeofd);

voidaddedge(intfrom,intto,intcost)

head[from]=cnt;

edge2[cnt].to=from;

//反向存图找从终点到其他点的最短路径

edge2[cnt].cost=cost;

edge2[cnt].next=head2[to];

head2[to]=cnt++;

boolspfa(ints)

memset(vis,0,sizeofvis);

queue<

q;

d[s]=0;

q.push(s);

q.empty())

intnow=q.front();

q.pop();

vis[now]=0;

for(inti=head2[now];

i=edge2[i].next)

if(d[now]+edge2[i].cost<

d[edge2[i].to])

d[edge2[i].to]=d[now]+edge2[i].cost;

vis[edge2[i].to])

vis[edge2[i].to]=1;

q.push(edge2[i].to);

intastar(ints,intt,intk)

if(s==t)k++;

//起点=终点则最短路为0要注意哦

if(d[s]==inf)return-1;

node1>

intcnt2=0;

node1tmp,to;

tmp.v=s;

tmp.g=0;

tmp.f=tmp.g+d[tmp.v];

q.push(tmp);

tmp=q.top();

if(tmp.v==t)

cnt2++;

if(cnt2==k)

returntmp.g;

for(inti=head[tmp.v];

to.v=edge[i].to;

to.g=tmp.g+edge[i].cost;

to.f=to.g+d[to.v];

q.push(to);

return-1;

intfrom,to,cost,start,end,k;

for(inti=0;

addedge(from,to,cost);

end,&

k);

spfa(end);

intans=astar(start,end,k);

ans);

4、Floyd

stdio.h>

#defineMAX1000000000

intn,m,p,i,j,st,end,q,d,k,t,time;

intdis[210],map[210][210];

intMin(inta,intb)

returna<

b?

a:

b;

voidfloyd()

for(k=1;

k<

k++)

for(j=1;

j<

j++)

map[i][j]=Min(map[i][j],map[i][k]+map[k][j]);

%d%d%d%d"

m,&

p,&

t)!

for(j=0;

j++)

map[i][j]=MAX;

map[i][i]=0;

}//将每一个区域之间的连接时间初始化为最大值,同一地区因为不需要花费时间移动所以初始化为0

st,&

map[st][end]=map[end][st]=1;

}//将数据中彼此连接的区域的连接时间赋值为1

floyd();

q);

while(q--)

d,&

time);

ints=map[p][d];

if(s>

time||s>

t)

YES\n"

NO\n"

}//判断能否起飞。

没什么好说的

\n"

三、

1、isap最大流

memory.h>

cmath>

#defineMAXN10005

#defineMAXE200000

#defineINF1e9

inttmp,src,des,cnt;

intn,m;

intfrom,to;

intnext,cap;

}edge[MAXE];

inthead[MAXN];

intgap[MAXN],dep[MAXN],cur[MAXN],stack[MAXN],top;

intISAP()

intcurfLow,maxfLow,u,insert,i;

memset(dep,0,sizeof(dep));

memset(gap,0,sizeof(gap));

memcpy(cur,head,n);

maxfLow=0;

u=src;

top=0;

while(dep[src]<

n)//整个循环当源点s的距离标号dep[s]>

=n时结束.

if(u==des)//当前顶点i为终点时增广

curfLow=INF;

top;

if(curfLow>

edge[stack[i]].cap)

insert=i;

curfLow=edge[stack[i]].cap;

++i

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 政史地

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1