1、3、问题再次被转化为“至少在缩点树上增加多少条树边,使得这棵树变为一个双连通图”。若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么至少增加的边数 =(这棵树总度数为1的结点数 + 1 )/ 24、若lowvdfnu,则(u,v)为割边。但是实际处理时我们并不这样判断,因为有的图上可能有重边,这样不好处理。我们记录每条边的标号(一条无向边拆成的两条有向边标号相同),记录每个点的父亲到它的边的标号,如果边(u,v)是v的父亲边,就不能用dfnu更新lowv。这样如果遍历完v的所有子节点后,发现lowv=dfnv,说明u的父亲边(u,v)为割边。void tarjan(int x)vis
2、x=1;dfnx=lowx=+num;for(int i=headx;i;i=nexti)if(!visveri) pveri=edgei;/记录父亲边tarjan(veri);lowx=min(lowx,lowveri);else if(px!=edgei)/不是父亲边才更新lowx=min(lowx,dfnveri);if(px&lowx=dfnx) fpx=1;/是割边PS:最大流=最小割一、1、邻接矩阵(略)2、邻接链表#include cstringalgorithmusing namespace std;const int N=102;struct EdgeNode int to;
3、 / 终点 int w; / 权值 EdgeNode *next; / 指向下一条边的指针 EdgeNode() next=NULL; ;struct VNode/ 起点表节点 int from; / 起点 EdgeNode *first; / 邻接表头指针AdjlistN; / 整个图的邻接表void addEdge(int a,int b,int wi) EdgeNode *p=new EdgeNode(); p-to=b;w=wi;next=Adjlista.first; Adjlista.first=p;void printEdge(int n) for (int i=1;inext)
4、 printf(vi=%d,vj=%d,w=%dn,i,k-to,k-w);void delEdge(int n)/ 把申请的边的内存空间释放掉,防止超内存 EdgeNode *p=Adjlisti.first; EdgeNode *k=NULL; while (p!=NULL) k=p-next; delete p; p=k;int visN;void dfs(int u) visu=1; for (EdgeNode *k =Adjlistu.first; if (!visk-to) dfs(k-to);void init(int n) Adjlisti.first=NULL; memset
5、(vis,0,sizeof(vis);int main() int n,m; while(scanf(%d%d,&n,&m)!=EOF) init(n); for (int a,b,i=0;m; scanf(a,&b); addEdge(a,b,1); dfs(1); int res=0; if (visi) res+;%dn,res); delEdge(n); return 0;3、链式前向星const int M=102;int headN;int tot; / 已申请节点的个数struct Edge int next;edgeM;void addEdge(int vi,int vj,in
6、t wi) edgetot.from=vi; edgetot.to=vj; edgetot.w=wi; edgetot.next=headvi; headvi=tot+; for (int i=headu;i!=-1;i=edgei.next)visedgei.to) dfs(edgei.to);void printEdges(int n) for (int j=headi;j!j=edgej.next),i,edgej.to,edgej.w);void init() tot=0; memset(head,-1,sizeof(head); while (scanf( init();二、1、Di
7、jkstra#includequeue#define MAX 0x3f3f3f3ftypedef pairP;struct node int to,cost; edge10000; int cnt;int n,start,end;int head5000;void add(int from,int to,int cost) edgecnt.to=to; edgecnt.cost=cost; edgecnt.next=headfrom; headfrom=cnt+;void dijkstra() int dis5000; int i,v; priority_queue P,vector,grea
8、terque; node e; P p; fill(dis,dis+n,MAX); disstart=0; que.push(P(0,start); while(!que.empty() p=que.top(); que.pop(); v=p.second; if(disvdisv+e.cost) dise.to=disv+e.cost; que.push(P(dise.to,e.to);,disend=MAX?-1:disend); int m,from,to,cost; while(scanf(m) cnt=0; while(m-)%d%d%dfrom,&to,&cost); add(fr
9、om,to,cost); add(to,from,cost);start,&end); dijkstra();2、spfa优化版(一般用于稀疏图)dequeconst int N=501;const int NN=100001;const int inf=0x7fffffff;int n,nu;int visN,disN,numN;typedef struct node int adj,val; struct node *next;node nodeNN,*pN;int SPFA(int start) deque qu; int x,i,a,b; struct node *headN; for
10、(i=1;i+) visi=0; numi=0; disi=inf; headi=pi; visstart=1; numstart+; qu.push_back(start);qu.empty() x=qu.front(); qu.pop_front(); visx=0; headx=px; while(headx) a=headx-adj; b=headx-val; if(disadisx+b) disa=disx+b; if(!visa) visa=1; numa+; if(numa=n) return 1; /如果要求一条负环回路上的点只需在这里改改就行disqu.front() qu.
11、push_back(a); else qu.push_front(a); headx=headx- int t,i,m,w,a,b,c;%dt); while(t-) memset(node,0,sizeof(node); memset(p,0,sizeof(p); nu=0;m); for(i=0;b,&c); nodenu.adj=b; nodenu.val=c; nodenu.next=pa; pa=&nodenu; nu+; nodenu.adj=a; nodenu.next=pb; pb=& if(SPFA(1) puts(YES);,disn);3、第k短路stringmap#de
12、fine inf 0x7fffffffconst int maxn=1010;int dmaxn,headmaxn,head2maxn,n,m,cnt;bool vismaxn; int to,cost,next;edge100010,edge2100010;struct node1 int v,g,f;/ f=g+h bool operator (const node1 &r) const if(r.f=f) return r.gg; return r.ff; memset(head,-1,sizeof head); memset(head2,-1,sizeof head2); memset
13、(d,0x3f,sizeof d);void addedge(int from,int to,int cost) headfrom=cnt; edge2cnt.to=from;/反向存图 找从终点到其他点的最短路径 edge2cnt.cost=cost; edge2cnt.next=head2to; head2to=cnt+;bool spfa(int s) memset(vis,0,sizeof vis); queue q; ds=0; q.push(s);q.empty() int now=q.front(); q.pop(); visnow=0; for(int i=head2now;i
14、=edge2i.next) if(dnow+edge2i.cost int cnt2=0; node1 tmp,to; tmp.v=s; tmp.g=0; tmp.f=tmp.g+dtmp.v; q.push(tmp); tmp=q.top(); if(tmp.v=t) cnt2+; if(cnt2=k) return tmp.g; for(int i=headtmp.v; to.v=edgei.to; to.g=tmp.g+edgei.cost; to.f=to.g+dto.v; q.push(to); return -1; int from,to,cost,start,end,k; for
15、(int i=0; addedge(from,to,cost);end,&k); spfa(end); int ans=astar(start,end,k);,ans);4、Floydstdio.h#define MAX 1000000000int n,m,p,i,j,st,end,q,d,k,t,time;int dis210,map210210;int Min(int a,int b) return a b ? a : b;void floyd() for(k=1;kk+) for(j=1;jtime|st)YESnNOn /判断能否起飞。没什么好说的n三、1、isap最大流memory.
16、hcmath#define MAXN 10005#define MAXE 200000#define INF 1e9int tmp,src,des,cnt;int n,m; int from,to; int next,cap;edgeMAXE;int headMAXN;int gapMAXN,depMAXN,curMAXN,stackMAXN,top;int ISAP() int curfLow,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(depsrc=n时结束. if(u=des)/当前顶点i为终点时增广 curfLow=INF;top; if(curfLowedgestacki.cap) insert=i; curfLow=edgestacki.cap;+i
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1