请问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]<=w(A,B)+dis[A]
即是满足题中的条件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;
}