请问spfa+stack 和spfa+queue 是什么原理
2014年03月19日 15:52:49
阅读数:472
一个是bfs加迭代
一个是dfs加迭代
请问迭代是什么
就是不断地做,做到没有更优的解为止
或者是不断得做,做到逼近答案为止。。
栈比队列更快更节省空间
有的时候有的图可能比较稀疏而且点数较多,邻接矩阵存不下,所以就要用到邻接表。邻接表用vector数组比较方便,但是vector比较慢。所以就有了链式向前星。 #include<iostream> #include<cstdio> #include<cstring> using namespace std; //链式向前星其实就是有n链表,每条链表存的是所有相同结点的边。 const int maxn=1100;//点数 const int maxm=11000;//边数 struct xx { int next,n,to; } node[maxm]; //每个结点存一条边,next表示与当前边起点一样的另一条边在弄的数组中的位置。to表示这条边的终点,n表示这条边的权值。 int head[maxn];//head[i]表示从i出发的点的链表的第一个点在node数组中的位置。 int num=0;//当前已有边的个数。 void Add(int from,int to,int n) { node[num].to=to; node[num].n=n; node[num].next=head[from];//当前结点指向以前的头结点 head[from]=num++;//当前结点变为头结点 } void Use(int i)//遍历起点为i的链表 { int t=head[i]; while(t!=-1) { cout<<"from "<<i<<"to "<<node[t].to<<"is "<<node[t].n<<endl; t=node[t].next; } } int main() { int from,to,n; memset(head,-1,sizeof(head)); memset(node,-1,sizeof(node)); while(cin>>from>>to>>n,from&&to&&n) { Add(from,to,n); } int i; cin>>i; Use(i); }
这是一题典型的差分约束题。不妨将糖果数当作距离,把相差的最大糖果数看成有向边AB的权值, 我们得到 dis[B]-dis[A]<=w(A,B)。看到这里,我们联想到求最短路时的松弛技术, 即if(dis[B]>dis[A]+w(A,B), dis[B]=dis[A]+w(A,B)。 即是满足题中的条件dis[B]-dis[A]<=w(A,B),由于要使dis[B] 最大, 所以这题可以转化为最短路来求。
#include<iostream> #include<cstdio> #include<stack> #include<cstring> using namespace std; #define inf 0x3f3f3f3f #define maxn 30005 #define maxm 150005 int n,m,x,y,z; int dis[maxn]; int head[maxn]; bool vis[maxn]; struct node { int nextone,w,v; } edge[maxm]; int num=0;//当前已有边的个数。 void Add(int from,int to,int w) { edge[num].v=to; edge[num].w=w; edge[num].nextone=head[from]; head[from]=num++; } void spfa() { memset(vis,0,sizeof(vis)); for(int i=1; i<=n; i++) dis[i]=inf; dis[1]=0; stack <int>stk; stk.push(1); vis[1]=0; while(!stk.empty()) { int temp=stk.top(); stk.pop(); vis[temp]=0; int idx=head[temp]; while(idx!=-1) { if(dis[edge[idx].v]>dis[temp]+edge[idx].w) { dis[edge[idx].v]=dis[temp]+edge[idx].w; if(!vis[edge[idx].v]) { stk.push(edge[idx].v); vis[edge[idx].v]=1; } } idx=edge[idx].nextone; } } } int main() { ios::sync_with_stdio(false); memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); while(m--) { scanf("%d%d%d",&x,&y,&z); Add(x,y,z); } spfa(); printf("%d\n",dis[n]); return 0; }